/* testlist.c - a solution to CS 12 assignment 3, part 2, Fall 2008 cmc, updated 10/28/08 */ #include #include #include #include "basiclist.h" #define MAXLINE 80 #define MAXITEM 50 /* max string to insert is 49 characters */ #define MAXOTHER 10 enum command { insert, delete, clear, advance, reset, show, quit, reject }; enum position { first, last, current, before, after, all, bad }; /* utility methods defined below main */ enum command identifyCommand(char *); enum position identifyPosition(enum command, char *); void *copyToken(char *); void printAll(ListPointer); void print(char *, void *); int main(void) { ListPointer list; char line[MAXLINE], token1[MAXOTHER], token2[MAXOTHER], token3[MAXITEM]; char *item; int tokenCount; enum command cmnd; enum position pos; list = createList(); while ((fgets(line, MAXLINE, stdin)) != NULL) { /* split line into tokens - just the first 3 matter */ tokenCount = sscanf(line, "%s %s %s", token1, token2, token3); /* ignore blank lines and comments */ if (tokenCount < 1 || token1[0] == '#') continue; /* first token is the primary command */ cmnd = identifyCommand(token1); switch (cmnd) { case quit: return 0; case reject: printf("bad command: %s\n", token1); break; case clear: clearList(list); printf("cleared\n"); break; case advance: advanceCurrent(list); print("advanced to:", currentInfo(list)); break; case reset: resetCurrent(list); print("reset to:", currentInfo(list)); break; default: /* insert, delete, and show are more complicated */ if (tokenCount < 2) { printf("missing position to %s\n", token1); break; } /* second token identifies position to carry out command */ pos = identifyPosition(cmnd, token2); if (pos == bad) printf("bad position: %s\n", token2); else if (cmnd == insert) { if (tokenCount < 3) printf("missing item to insert\n"); else { /* third token is the item to insert */ item = copyToken(token3); if (pos == first) { insertFirst(item, list); printf("inserted first: %s\n",item); }else if (pos == last) { insertLast(item, list); printf("inserted last: %s\n",item); }else if (pos == before) { insertBeforeCurrent(item, list); printf("inserted before current: %s\n",item); }else { insertAfterCurrent(item, list); printf("inserted after current: %s\n",item); } } }else if (cmnd == delete) { if (pos == first) item = deleteFirst(list); else if (pos == last) item = deleteLast(list); else item = deleteCurrent(list); print("deleted:", item); free(item); }else { /* cmnd == show */ if (pos == first) print("first item:", firstInfo(list)); else if (pos == last) print("last item:", lastInfo(list)); else if (pos == current) print("current item:", currentInfo(list)); else printAll(list); } break; } } return 0; } /* identify the command given by the token */ enum command identifyCommand(char *token) { if (!strcmp("insert", token)) return insert; if (!strcmp("delete", token)) return delete; if (!strcmp("clear", token)) return clear; if (!strcmp("advance", token)) return advance; if (!strcmp("reset", token)) return reset; if (!strcmp("show", token)) return show; if (!strcmp("quit", token)) return quit; return reject; } /* identify the position given by the token validity depends on the command */ enum position identifyPosition(enum command cmnd, char *token) { if (!strcmp("first", token)) return first; if (!strcmp("last", token)) return last; if (cmnd == delete || cmnd == show) if (!strcmp("current", token)) return current; if (cmnd == insert) { if (!strcmp("before", token)) return before; if (!strcmp("after", token)) return after; } if (cmnd == show) if (!strcmp("all", token)) return all; return bad; } /* allocate space for new string and copy token to it */ void *copyToken(char *token) { char *p; size_t length = strlen(token); p = malloc((length+1) * sizeof(char)); strcpy(p, token); return p; } /* prints "[tag] ", followed by item value or "null", and newline */ void print(char *tag, void *item) { printf("%s ", tag); if (item != NULL) printf("%s\n", (char *)item); else printf("NULL\n"); } /* custom display function for a list that holds strings Note: unavoidably moves the current pointer, so resets when done. */ void printAll(ListPointer list) { printf("list: ("); resetCurrent(list); if (!emptyList(list)) printf("%s", (char *)(firstInfo(list))); while (hasMoreInfo(list)) { advanceCurrent(list); printf(",%s", (char *)(currentInfo(list))); } resetCurrent(list); printf(")\n"); }