#include #include "rectangle.h" #include "fields.h" #include "jrb.h" #include Rectangle *readRect(IS is) { int i, j; char label[1000]; int left, top, width, height; if (is->NF < 6) { fprintf(stderr, "Line %d: Not enough info\n", is->line); exit(1); } // the last field is the color and we do not need to convert it // since it is already a string. Therefore decrement i by 2 so // that it points to the height field. i = is->NF - 2; if (sscanf(is->fields[i], "%d", &height) != 1) { fprintf(stderr, "Line %d: Bad height\n", is->line); exit(1); } i--; if (sscanf(is->fields[i], "%d", &width) != 1) { fprintf(stderr, "Line %d: Bad width\n", is->line); exit(1); } i--; if (sscanf(is->fields[i], "%d", &top) != 1) { fprintf(stderr, "Line %d: Bad top\n", is->line); exit(1); } i--; if (sscanf(is->fields[i], "%d", &left) != 1) { fprintf(stderr, "Line %d: Bad left\n", is->line); exit(1); } /* we've finished processing all the words to the right of the label. We know that any remaining words must belong to the label so we start at the leftmost word and work our way towards the rightmost word. We initialize label by copying the leftmost word into label. Thereafter we add additional words by repetitively concatenating a blank space and an additional word. */ for (j = 0; j < i; j++) { if (j > 0) { strcat(label, " "); strcat(label, is->fields[j]); } else { strcpy(label, is->fields[j]); } } return new Rectangle(left, top, width, height, label, is->fields[is->NF-1]); } main(int argc, char **argv) { Rectangle *r; IS is; JRB tree, tmp; int x, y; char sort_order; // Process the command line if (argc != 4) { fprintf(stderr, "usage: HitDetect -x|-y x y\n"); exit(1); } if (strcmp(argv[1], "-x") != 0 && strcmp(argv[1], "-y") != 0) { fprintf(stderr, "usage: HitDetect -x|-y x y\n"); exit(1); } if ((sscanf(argv[2], "%d", &x) != 1) || (sscanf(argv[3], "%d", &y) != 1)) { fprintf(stderr, "usage: HitDetect x y\n"); fprintf(stderr, "x and y must be integers\n"); exit(1); } /* argv[1] = "-x" or "-y" so argv[1][1] is equal to either 'x' or 'y' */ sort_order = argv[1][1]; // Initialize the inputstruct and the tree is = new_inputstruct(NULL); tree = make_jrb(); // Read the file, creating rectangles for each line and inserting them // into the tree. while (get_line(is) >= 0) { if (is->NF == 0) continue; /* blank line of input */ r = readRect(is); /* insert the rectangle into the tree based on either its left or top--the order in which rectangles are stored is determined by sort_order */ switch (sort_order) { case 'x': jrb_insert_int(tree, r->getLeft(), new_jval_v(r)); break; case 'y': jrb_insert_int(tree, r->getTop(), new_jval_v(r)); break; default: fprintf(stderr, "Internal program error -- this shouldn't happen\n"); exit(1); } } // Traverse the tree and print out all the rectangles that contain // the given point. jrb_traverse(tmp, tree) { r = (Rectangle *) tmp->val.v; if (r->containsPt(x, y)) { if (sort_order == 'x') printf("%4d %s\n", r->getLeft(), r->getLabel()); else printf("%4d %s\n", r->getTop(), r->getLabel()); } } }