rendered paste body#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#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;
}