コード例 #1
0
ファイル: read-command.c プロジェクト: aushtin/cs111_practice
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;
}
コード例 #2
0
 int calculate(string s) {
     eatWhiteSpaces(s);
     //return expr(s, false);
     int pos = 0;
     return (evaluate(s, pos));
 }