/* testpoly.c Tests poly.c Use for CS 60 assignment 3 testing purposes. Do not rely on changes to this file - you will not turn it in. Must be linked to poly.o for proper execution (also remember to link to the math library, -lm, since poly.c includes math.h). We suggest you use a Makefile to accomplish the necessary steps. Reads from standard input. User either types commands at the keyboard, or preferably redirects an input file. Such input files must have one command per line. Blank lines and lines in which the first non-blank character is '#' are simply echoed. If run with -i option, then creates initial polynomials (in order to test parts without using addTerm). cmc, updated 10/22/09 */ #include #include #include #include #include "poly.h" #define MAXLINE 80 #define MAXCMND 10 enum command { add, val, deg, cnt, sum_, dif, mul, pri, clr, bad }; int main(int argc, char **argv) { Poly p[2]; /* array of 2 poly pointers */ Poly temp; enum command cmnd; int arg1, arg3; /* commands have 0 to 3 arguments */ double arg2; /* for add & val, 2nd argument is double */ char line[MAXLINE+1], cmndString[MAXCMND+1]; int length, firstNonBlank, tokenCount; /* utility functions defined below */ void initialPolygons(Poly[]); enum command identifyCommand(char *); int validPoly(int); void printPoly(Poly); /* create initial polygons if -i option used */ if (argc > 1 && strcmp(argv[1], "-i") == 0) initialPolygons(p); else p[0] = p[1] = NULL; while ((fgets(line, MAXLINE, stdin)) != NULL) { /* just echo blank lines and comments */ length = strlen(line); firstNonBlank = strspn(line, " \t\n\r"); if (length == 1 || firstNonBlank == length || line[firstNonBlank] == '#') { printf("%s", line); continue; } /* split line into tokens - just the first 4 matter */ tokenCount = sscanf(line, "%s %d %lg %d", cmndString, &arg1, &arg2, &arg3); cmnd = identifyCommand(cmndString); switch (cmnd) { case bad: printf("bad command: %s\n", cmndString); break; case add: if (tokenCount < 4) printf("[incomplete add request:] %s", line); else if (!validPoly(arg1)) printf("[bad polynomial number:] %d\n", arg1); else if (arg3 < 0) printf("[invalid exponent < 0:] %d\n", arg3); else { if (arg1 == 1) addTerm(arg2, arg3, &p[0]); else addTerm(arg2, arg3, &p[1]); printf("added %gx^%d to poly %d\n",arg2, arg3, arg1); } break; case deg: case cnt: case pri: case clr: case val: if (tokenCount < 2) printf("[incomplete request:] %s", line); else if (validPoly(arg1)) { Poly *ptr = &p[arg1 - 1]; if (cmnd == deg) printf("poly %d degree = %d\n", arg1, degree(*ptr)); else if (cmnd == cnt) { int c = count(*ptr); printf("poly %d has %d term%s\n", arg1, c, (c != 1 ? "s" : "") ); } else if (cmnd == pri) { printf("poly %d = ", arg1); printPoly(*ptr); printf("\n"); } else if (cmnd == clr) { freePoly(ptr); printf("cleared poly %d\n", arg1); } else { /* cmnd == val */ /* re-scan for arg3 as double in 2nd position tokenCount = sscanf(line, "%s %d %lg", cmndString, &arg1, &arg3); */ if (tokenCount > 2) printf("poly %d value at %g = %g\n", arg1, arg2, value( p[arg1 - 1], arg2) ); else printf("[bad value command:] %s", line); } } else printf("[bad polynomial number:] %d\n", arg1); break; case sum_: temp = sum(p[0], p[1]); printf("sum(poly 1, poly 2) = "); printPoly(temp); printf("\n"); freePoly(&temp); break; case mul: temp = mult(p[0], p[1]); printf("mult(poly 1, poly 2) = "); printPoly(temp); printf("\n"); freePoly(&temp); break; case dif: if (tokenCount < 3) printf("[incomplete command:] %s", line); else { int iarg2 = (int)arg2; if (!validPoly(arg1) || !validPoly(iarg2)) printf("[invalid poly number(s):] %s", line); else { Poly first = p[arg1 - 1]; Poly second = p[iarg2 - 1]; temp = diff(first, second); printf("diff(poly %d, poly %d) = ", arg1, iarg2); printPoly(temp); printf("\n"); freePoly(&temp); } } break; } } /* clean up, and print results of memory allocations/deallocations */ freePoly(&p[0]); freePoly(&p[1]); { int tc = termsCreated(), tf = termsFreed(), tr = tc - tf; printf("\nDone.\n Created %d terms.\n Freed %d terms.\n", tc, tf); if (tr > 0) printf(" *** WARNING: %d terms remain allocated ***\n", tr); else if (tr < 0) printf(" ?! Strange: freed more terms than created !?\n"); else printf(" All terms freed successfully.\n"); } return 0; } /* creates initial polygons for testing if -i option on command line */ void initialPolygons(Poly p[]) { p[0] = newTerm(15.5, 5); p[0]->next = newTerm(10.75, 3); p[0]->next->next = newTerm(5.4, 1); p[0]->next->next->next = newTerm(17.2, 0); p[1] = newTerm(-4.2, 4); p[1]->next = newTerm(0.7, 2); p[1]->next->next = newTerm(-8.4, 1); } /* identify the command given by the token */ enum command identifyCommand(char *token) { if (!strcmp("add", token)) return add; if (!strcmp("value", token)) return val; if (!strcmp("degree", token)) return deg; if (!strcmp("count", token)) return cnt; if (!strcmp("sum", token)) return sum_; if (!strcmp("diff", token)) return dif; if (!strcmp("mult", token)) return mul; if (!strcmp("clear", token)) return clr; if (!strcmp("print", token)) return pri; return bad; /* not a valid command */ } /* utility function checks value of polynomial number */ int validPoly(int value) { return value == 1 || value == 2; } /* prints a polynomial to stdout (e.g, "25.2x^4 + 7.1x^2 - 4x + 2.3 */ void printPoly(Poly p) { void printAbsTerm(Term *); /* utility function defined below */ Term *t = p; if (t == NULL) { printf("0"); return; } /* print first term */ if (t->coeff < 0) printf("-"); printAbsTerm(t); /* loop through and print remaining terms */ for (t = t->next; t != NULL; t = t->next) if (t->coeff > 0.) { printf(" + "); printAbsTerm(t); } else { printf(" - "); printAbsTerm(t); } } /* utility used by printPoly - prints absolute value of one term; assumes t is not NULL */ void printAbsTerm(Term *t) { double absCoeff = fabs(t->coeff); if (absCoeff != 1. || t->exponent == 0) printf("%g", absCoeff); if (t->exponent == 1) printf("x"); else if (t->exponent != 0) printf("x^%u", t->exponent); }