#include #include #include #include #include #include "move.h" /* Define constants for the max sizes of things */ #define MAX_FIG 16 /* Max number of figures allowed */ #define MAX_FIG_SEG 17 /* Max number of segments per figure 16 + 1*/ #define MAX_FIG_NAME 128 /* Max size of the figure names */ #define MAX_LINE_LENGTH 256 /* Maximum size of input lines */ #define M_PI 3.1415926535897932384626433832795029L /* pi from math.h */ FILE* FILTER; FILE *popen(const char *command, const char *type); int pclose(FILE *stream); long int lround(double x); /* If -DDEBUG=1 set at compile time, set debug to 1, else set it to 0 * May not be ideal, but it is sufficient for the time being * maybe add command line -debug parser? */ #if defined (DEBUG) #define DEBUG 1 #else #define DEBUG 0 #endif /* Define the structure of the figure data */ struct figStruct { char name[MAX_FIG_NAME]; double segments[MAX_FIG_SEG+1][2]; }; /* Function definitions, functions are below */ static int printFigure(int cur_fig , struct figStruct * figure); static int drawFigure(int cur_fig , struct figStruct * figure); static int translateFigure(int cur_fig , struct figStruct * figure, char *, char *); static int rotateFigure(int cur_fig , struct figStruct * figure, char *); /* Function to parse individual tokens, and make decisions based on the * commands on each line. Fills data into the struct, and handles all * required commands */ int parseToken ( char* tokenline, double* cur_y, double* cur_x, float* direction, int* cur_fig, struct figStruct *figure) { char* operator = strtok(tokenline," "); int index=0; if ( DEBUG ) { printf("parsing %s\n", tokenline); } if ( ! strncmp(operator,"Figure", MAX_LINE_LENGTH) ) { int index2 = 0; for ( index=0; index < MAX_FIG; index++ ) { if ( ! *figure[index].name ) { strncpy( figure[index].name,strtok(NULL, " "), MAX_LINE_LENGTH); figure[index].segments[0][0] = 0; figure[index].segments[0][1] = 0; *direction = (M_PI/180) * 90; for ( index2 = 0 ; index2 < MAX_FIG_SEG; index2++ ) { figure[index].segments[index2][0] = 0; figure[index].segments[index2][1] = 0; } *cur_fig = index; return 0; } } return -1; } if ( ! strncmp(operator,"start", MAX_LINE_LENGTH) ) { figure[*cur_fig].segments[0][0] = atoi(strtok(NULL, " ")); figure[*cur_fig].segments[0][1] = atoi(strtok(NULL, " ")); return 0; } if ( ! strncmp(operator,"face", MAX_LINE_LENGTH) ) { *direction = atof(strtok(NULL, " ")); /* read in direction, and convert to radian */ *direction = (M_PI / 180) * *direction; return 0; } if ( ! strncmp(operator,"draw", MAX_LINE_LENGTH) ) { double draw_length = atoi(strtok(NULL, " ")); for ( index=1; index < MAX_FIG_SEG; index++ ) { if ( ! figure[*cur_fig].segments[index][0] ) { figure[*cur_fig].segments[index][0] = (cos(*direction) * draw_length) + figure[*cur_fig].segments[index-1][0]; figure[*cur_fig].segments[index][1] = (sin(*direction) * draw_length) + figure[*cur_fig].segments[index-1][1]; if ( DEBUG ) { printf("drawing %lf %lf %lf %lf %lf\n", draw_length, figure[*cur_fig].segments[index][0], figure[*cur_fig].segments[index][1], figure[*cur_fig].segments[index-1][0], figure[*cur_fig].segments[index-1][1]); } return 0; } } } if ( ! strncmp(operator,"printFigure", MAX_LINE_LENGTH)) { char* fig_name = strtok(NULL, " "); int index=0; for ( index=0; index < MAX_FIG; index++ ) { if ( ! strncmp(figure[index].name, fig_name, sizeof(*figure[index].name))) { printFigure(index, figure); } } return 0; } if ( ! strncmp(operator,"drawFigure", MAX_LINE_LENGTH)) { char* fig_name = strtok(NULL, " "); int index=0; for ( index=0; index < MAX_FIG; index++ ) { if ( ! strncmp(figure[index].name, fig_name, sizeof(*figure[index].name))) { drawFigure(index, figure); } } return 0; } if ( ! strncmp(operator,"pipe", 4)) { char* pipe_payload = strtok(NULL, ""); if (pipe_payload) { fprintf(FILTER,"%s %s", (operator+4), pipe_payload ); return 0; } fprintf(FILTER,"%s", (operator+4)); return 0; } if ( ! strncmp(operator,"End", MAX_LINE_LENGTH) ) { *cur_fig = -1; return 0; } if ( ! strncmp(operator,"translate", MAX_LINE_LENGTH) ) { char* fig_name = strtok(NULL, " "); int index=0; for ( index=0; index < MAX_FIG; index++ ) { if ( ! strncmp(figure[index].name, fig_name, sizeof(*figure[index].name))) { translateFigure(index, figure, strtok(NULL, " "), strtok(NULL, " ")); } } return 0; } if ( ! strncmp(operator,"rotate", MAX_LINE_LENGTH) ) { char* fig_name = strtok(NULL, " "); int index=0; for ( index=0; index < MAX_FIG; index++ ) { if ( ! strncmp(figure[index].name, fig_name, sizeof(*figure[index].name))) { rotateFigure(index, figure, strtok(NULL, " ")); } } return 0; } if ( ! strncmp(operator, "#", 1)) { char* comment_line = strtok(NULL,""); if ( comment_line ) { printf("%s%s", operator ,comment_line); return 0; } printf("%s", operator); } /* Just eat lines that start with spaces */ if ( ! strncmp(operator, " ", 1)) { return 0; } if (DEBUG) { fprintf(stderr, "Unsupported token read : %s %s\n", operator, strtok(NULL, "")); } return 1; } int parseInputFile ( char * filename, struct figStruct * figure ) { char buf[MAX_LINE_LENGTH]; /* buffer to read file into */ FILE *fh; /* File handle for read */ int curfig = 0; /* Current figure that we are looking at set to 0 */ double cur_x, cur_y; float direction; if ((fh = fopen(filename, "r")) == NULL) { fprintf(stderr, "Cannot open %s\n", filename); } /* Walk through the file one line at a time and populate the struct */ while( fgets(buf, MAX_LINE_LENGTH ,fh) ) { if ( buf ) { parseToken (buf, &cur_x, &cur_y, &direction, &curfig, figure); } } fclose(fh); return 0; } /* Main function */ int main(int argc, char** argv) { struct figStruct figure[MAX_FIG]; int index = 0; /* If we have no CLI options, we die */ if ( argc <= 1 ) { printf("ERROR: No Command line arguments supplied, exiting\n"); return 1; } /* Let's grab the filename off of the command line */ if ( DEBUG ) { printf("DEBUG: Opening %s\n", argv[1]); } /* Init the struct */ for ( index=0; index < MAX_FIG; index++ ) { *figure[index].name = 0; } printf("%s started on ", argv[0]); fflush(stdout); system("date"); printf("Input file: %s\n", argv[1]); FILTER = popen("./filter", "w"); parseInputFile(argv[1], figure); pclose(FILTER); return 0; } int printFigure ( int cur_fig, struct figStruct *figure ) { int index=0; printf("Print Figure %s =\n", figure[cur_fig].name); for ( index=0; index < MAX_FIG_SEG; index++ ) { if ( figure[cur_fig].segments[index][0] ) { printf("%3.3f %3.3f\n", figure[cur_fig].segments[index][0], figure[cur_fig].segments[index][1]); } } printf("End Figure %s =\n", figure[cur_fig].name); return 0; } int drawFigure ( int cur_fig, struct figStruct *figure ) { int index=0; for ( index=1; index < MAX_FIG_SEG; index++ ) { if ( figure[cur_fig].segments[index][0] ) { fprintf(FILTER, "drawSegment %ld %ld %ld %ld\n", lround(figure[cur_fig].segments[index-1][0]),lround(figure[cur_fig].segments[index-1][1]), lround(figure[cur_fig].segments[index][0]), lround(figure[cur_fig].segments[index][1])); } } return 0; } /* This would have been easier if I used the point struct inside of the figure struct, maybe v2.0 */ int translateFigure ( int cur_fig, struct figStruct *figure, char* t_x, char* t_y) { point p; int index = 0; for ( index=0; index < MAX_FIG_SEG; index++ ) { if ( figure[cur_fig].segments[index][0] ) { p.x = figure[cur_fig].segments[index][0]; p.y = figure[cur_fig].segments[index][1]; p = translate_point(p, atof(t_y), atof(t_x)); figure[cur_fig].segments[index][0] = p.x; figure[cur_fig].segments[index][1] = p.y; } } return 0; } int rotateFigure ( int cur_fig, struct figStruct *figure, char* rotateby) { point p; int index = 0; for ( index=0; index < MAX_FIG_SEG-1; index++ ) { if ( figure[cur_fig].segments[index][0] ) { p.x = figure[cur_fig].segments[index][0]; p.y = figure[cur_fig].segments[index][1]; p = rotate_point(p, atof(rotateby)); figure[cur_fig].segments[index][0] = p.x; figure[cur_fig].segments[index][1] = p.y; } } return 0; }