command_stream_t make_command_stream (int (*get_next_byte) (void *), void *get_next_byte_argument) { //current character char curr; int tree_number = 1; char prev_char_stored = '\0'; int consecutive_newlines = 0; //buffer size = 1KB int BUFFER_SIZE = 1024; //buffer to read characters into; buffer can hold 1024 chars at once char *buffer = (char *) checked_malloc(BUFFER_SIZE * sizeof(char)); //int to count how many chars are in buffer int numChars = 0; //int to count which line we are on //int syntax_line_counter = 0; int invalid_char_line_counter = 1; //if this is true, we are searching for the right operand of an operator bool found_AND_OR_PIPE_SEQUENCE = false; //looking for operand //declare command stream and allocate space //maybe dont need to allocate space because initStream() already does? command_stream_t theStream; // = (command_stream_t) checked_malloc(sizeof(struct command_stream)); //initialize command_stream theStream = initStream(); //start reading the chars from the input while ((curr = get_next_byte(get_next_byte_argument)) != EOF ) { if (numChars > 0){ //only stores previous meaningful character, i.e. not whitespace if ((buffer[numChars-1] != ' ' && buffer[numChars-1] != '#')){ prev_char_stored = buffer[numChars-1]; } } if (prev_char_stored == '&' || prev_char_stored == '|' || prev_char_stored == ';'){ found_AND_OR_PIPE_SEQUENCE = true; } //////////////////////////////////////////////////////////// ////////////////// NEWLINE CHAR //////////////////// //////////////////////////////////////////////////////////// /* New variables introduced: char prev_char_stored; int consecutive_newlines; bool command_has_ended; //haven't needed to use yet */ if (identify_char_type(curr) == NEWLINE_CHAR || identify_char_type(curr) == HASHTAG_CHAR){ //found a newline, increment counter consecutive_newlines++; //hit second (or more) newline if (consecutive_newlines > 1){ //not looking for an operator and if (!found_AND_OR_PIPE_SEQUENCE){ if (identify_char_type(curr) == NEWLINE_CHAR) { //add second newline to buffer buffer[numChars] = '\n'; numChars++; curr = get_next_byte(get_next_byte_argument); } /* check for newlines, whitespaces, and hashtags after second newline Store newlines on the buffer, ignore white spaces, and for hashtags: put hashtag and newline on the buffer */ while (identify_char_type(curr) == NEWLINE_CHAR || identify_char_type(curr) == WHITESPACE_CHAR || identify_char_type(curr) == HASHTAG_CHAR){ if (curr == '\n'){ buffer[numChars] = '\n'; numChars++; } else if (curr == '#'){ //add hashtag to buffer consecutive_newlines++; buffer[numChars] = '#'; numChars++; //go to end of comment while (identify_char_type(curr) != NEWLINE_CHAR){ if ((curr = get_next_byte(get_next_byte_argument)) == EOF) { break; } } //broke out of loop, curr is now a newline char; add to buffer buffer[numChars] = '\n'; numChars++; } if ((curr = get_next_byte(get_next_byte_argument)) == EOF) { break; } } consecutive_newlines = 0; //create temporary array with size of numChars; char* buffer_no_whitespaces = checked_malloc(BUFFER_SIZE * (sizeof(char))); //the correct syntaxed command memset(buffer_no_whitespaces, '\0', BUFFER_SIZE * sizeof(char)); //run validation, then parse if correct eatWhiteSpaces(buffer, numChars, buffer_no_whitespaces); int pos = 0; while (buffer_no_whitespaces[pos] != '\0'){ if (identify_char_type(buffer_no_whitespaces[pos]) == NEWLINE_CHAR){ invalid_char_line_counter++; } if (identify_char_type(buffer_no_whitespaces[pos]) == INVALID_CHAR){ identify_char_type(buffer_no_whitespaces[pos]); fprintf(stderr, "%d: Invalid character: %c <---", invalid_char_line_counter, buffer_no_whitespaces[pos]); exit(1); } pos++; } checkAndSyntax(buffer_no_whitespaces); checkForConsecutiveTokens(buffer_no_whitespaces); checkIfOperatorsHaveOperands(buffer_no_whitespaces); validParentheses(buffer_no_whitespaces); /* int i; for (i= 0; i<numChars; i++){ printf("%c", buffer_no_whitespaces[i]); } //this just separates commands printf("\n"); */ commandNode_t root = createNodeFromCommand(make_command_tree(buffer_no_whitespaces)); //printf("adding command node to stream: %s\n", root->cmd->u.word[0]); write_list_t write_list = init_write_list(); //printf("adding command node to stream: %s\n", root->cmd->u.word[0]); root->write_list = make_write_list(write_list, root->cmd); read_list_t read_list = init_read_list(); root->read_list = make_read_list(read_list, root->cmd); root->tree_number=tree_number; root->dependency_list = (commandNode_t*)(checked_realloc(root->dependency_list, (tree_number) * sizeof(commandNode_t))); memset (root -> dependency_list, '\0', (tree_number) * sizeof(commandNode_t)); //printf("adding command node to stream: %s\n", root->cmd->u.word[0]); addNodeToStream(theStream, root); //reset everything with memset memset(buffer, '\0', BUFFER_SIZE * sizeof(char)); free(buffer_no_whitespaces); numChars = 0; consecutive_newlines = 0; tree_number++; if (curr == EOF) break; /* We are now at a new command. Add first character to buffer, whether valid or invalid. Will check syntax later. */ if (identify_char_type(curr) != HASHTAG_CHAR){ buffer[numChars] = curr; numChars++; } else { //add a hashtag and newline to the buffer buffer[numChars] = '#'; numChars++; //get to the end of the line while (identify_char_type(curr) != NEWLINE_CHAR){ if ((curr = get_next_byte(get_next_byte_argument)) == EOF) { break; } } //now we have a newline; add newline to buffer buffer[numChars]=curr; numChars++; consecutive_newlines++; } continue; } else { //if we are looking for operand, don't end the commmand while (identify_char_type(curr) == NEWLINE_CHAR || identify_char_type(curr) == WHITESPACE_CHAR || identify_char_type(curr) == HASHTAG_CHAR){ if (curr == '\n'){ buffer[numChars] = '\n'; numChars++; } else if (curr == '#'){ //add hashtag to buffer buffer[numChars] = '#'; numChars++; while (identify_char_type(curr) != NEWLINE_CHAR){ if ((curr = get_next_byte(get_next_byte_argument)) == EOF) { break; } } //broke out of loop, curr is now a newline char; add to buffer buffer[numChars] = '\n'; numChars++; } if ((curr = get_next_byte(get_next_byte_argument)) == EOF) { break; } } //broken out of while loop, we now have a regular character; add to buffer if (curr == EOF) break; buffer[numChars] = curr; numChars++; found_AND_OR_PIPE_SEQUENCE = false; consecutive_newlines = 0; continue; } } else { //add newline to buffer; this is when number of newlines equals one if (identify_char_type(curr) == HASHTAG_CHAR) { buffer[numChars] = '#'; numChars++; while (identify_char_type(curr) != NEWLINE_CHAR){ if ((curr = get_next_byte(get_next_byte_argument)) == EOF) { break; } } } buffer[numChars] = '\n'; numChars++; continue; } } //end newline case else { if (!found_AND_OR_PIPE_SEQUENCE && consecutive_newlines == 1) { buffer[numChars] = ';'; numChars++; } buffer[numChars] = curr; numChars++; consecutive_newlines = 0; //if we are here we no longer skip lines found_AND_OR_PIPE_SEQUENCE = false; } } char* buffer_no_whitespaces = checked_malloc(BUFFER_SIZE * (sizeof(char))); //the correct syntaxed command memset(buffer_no_whitespaces, '\0', BUFFER_SIZE * sizeof(char)); //run validation, then parse if correct //void eatWhiteSpaces(char *buffer, int bufferSize, char *newArray) eatWhiteSpaces(buffer, numChars, buffer_no_whitespaces); int pos = 0; while (buffer_no_whitespaces[pos] != '\0'){ if (identify_char_type(buffer_no_whitespaces[pos]) == NEWLINE_CHAR){ invalid_char_line_counter++; } if (identify_char_type(buffer_no_whitespaces[pos]) == INVALID_CHAR){ identify_char_type(buffer_no_whitespaces[pos]); fprintf(stderr, "%d: Invalid character: %c <---", invalid_char_line_counter, buffer_no_whitespaces[pos]); exit(1); } pos++; } checkAndSyntax(buffer_no_whitespaces); checkForConsecutiveTokens(buffer_no_whitespaces); checkIfOperatorsHaveOperands(buffer_no_whitespaces); validParentheses(buffer_no_whitespaces); /* if (buffer_no_whitespaces[0] != '\0') { int i; for (i= 0; i<numChars; i++){ printf("%c", buffer_no_whitespaces[i]); } printf("\n"); }*/ //make sure buffer_no_whitespace is not empty if (buffer_no_whitespaces[0] != '\0') { commandNode_t root = createNodeFromCommand(make_command_tree(buffer_no_whitespaces)); write_list_t write_list = init_write_list(); root->write_list = make_write_list(write_list, root->cmd); read_list_t read_list = init_read_list(); root->read_list = make_read_list(read_list, root->cmd); root->tree_number=tree_number; root->dependency_list = (commandNode_t*)(checked_realloc(root->dependency_list, (tree_number) * sizeof(commandNode_t))); memset (root -> dependency_list, '\0', (tree_number) * sizeof(commandNode_t)); //printf("adding command node to stream: %s\n", root->cmd->u.word[0]); addNodeToStream(theStream, root); } free(buffer); free(buffer_no_whitespaces); theStream->blocked_commands = (commandNode_t*)checked_realloc(theStream->blocked_commands, theStream->num_nodes * sizeof(commandNode_t)); memset(theStream->blocked_commands, '\0', theStream->num_nodes * sizeof(commandNode_t)); return theStream; }
int calculate(string s) { eatWhiteSpaces(s); //return expr(s, false); int pos = 0; return (evaluate(s, pos)); }