#include #include #include #define CMDS_DEL "." #define CMDS_DEL_NL ".\n" #define MODE_CMD 1 #define MODE_TEXT 2 #define MODE_END 3 #define CMD_BUFFER 1024 #define CMD_DELIMITER ";" #define CMD_PRINT 'p' #define CMD_QUIT 'q' #define CMD_APPENDS 'a' #define CMD_REPLACE 'r' #define CMD_DELETE 'd' #define CMD_INSERT 'i' int main (void) { char* buffer = NULL; int buffer_size = 0; int buffer_length = 0; int chars_read = 0; int program_mode = MODE_CMD; int line_number = 0; int char_pos = 0; char valid_cmds[CMD_BUFFER + 1] = {'\0'}; char* all_cmds = NULL; char* cmd_line = NULL; int number = 0; int number_b = 0; char letter; char symbol; char commatilde; char* string = NULL; int skip_print = 0; do { chars_read = getline(&buffer, &buffer_size, stdin); if(chars_read < 1){ break; } if(strcmp(buffer, CMDS_DEL) == 0 || strcmp(buffer, CMDS_DEL_NL) == 0){ program_mode = program_mode + 1; continue; } if(program_mode == MODE_CMD){ buffer_length = strlen(buffer); for(char_pos = 0; char_pos < buffer_length; char_pos++){ if(islower(buffer[char_pos])){ if(buffer[char_pos] == CMD_PRINT || buffer[char_pos] == CMD_QUIT || buffer[char_pos] == CMD_APPENDS || buffer[char_pos] == CMD_REPLACE || buffer[char_pos] == CMD_DELETE || buffer[char_pos] == CMD_INSERT ){ strcat(valid_cmds, buffer); strcat(valid_cmds, CMD_DELIMITER); break; } program_mode = MODE_END; break; } } } if(program_mode == MODE_TEXT){ skip_print = 0; line_number = line_number + 1; all_cmds = strdup(valid_cmds); for(cmd_line = strtok(all_cmds, CMD_DELIMITER); cmd_line != NULL; cmd_line = strtok(NULL, CMD_DELIMITER)){ // most specific - 6 parameters, 2 of which are verified if(sscanf("%d%c%d%c%c%s", &number, &commatilde, &number_b, &symbol, &letter, string) == 6 && (commatilde == ',' || commatilde == '~') && symbol == '!'){ if(letter = CMD_APPENDS && ( (commatilde == ',' && number < line_number || line_number > number_b) || (commatilde == '~' && (number != line_number && (line_number - number % number_b) > 0)) )){ strcat(buffer, "\n"); strcat(buffer, string); } if(letter = CMD_REPLACE && ( (commatilde == ',' && number < line_number || line_number > number_b) || (commatilde == '~' && (number != line_number && (line_number - number % number_b) > 0)) )){ strcpy(buffer, string); } if(letter = CMD_INSERT && ( (commatilde == ',' && number < line_number || line_number > number_b) || (commatilde == '~' && (number != line_number && (line_number - number % number_b) > 0)) )){ strcat(string, "\n"); strcat(string, buffer); strcpy(buffer, string); } // this is next cause it's 5, 2 of which are verified. }else if(sscanf("%d%c%d%c%c", &number, &commatilde, &number_b, &symbol, &letter) == 5 && (commatilde == ',' || commatilde == '~') && symbol == '!'){ if(letter = CMD_PRINT && ( (commatilde == ',' && number < line_number || line_number > number_b) || (commatilde == '~' && (number != line_number && (line_number - number % number_b) > 0)) )){ printf("%s", buffer); } if(letter = CMD_DELETE && ( (commatilde == ',' && number < line_number || line_number > number_b) || (commatilde == '~' && (number != line_number && (line_number - number % number_b) > 0)) )){ skip_print = 1; } // then this because it's also 5, 1 of which is verified. }else if(sscanf("%d%c%d%c%s", &number, &commatilde, &number_b, &letter, string) == 5 && (commatilde == ',' || commatilde == '~')){ if(letter = CMD_APPENDS && ( (commatilde == ',' && number >= line_number && line_number <= number_b) || (commatilde == '~' && (number == line_number || (line_number - number % number_b) == 0)) )){ strcat(buffer, "\n"); strcat(buffer, string); } if(letter = CMD_REPLACE && ( (commatilde == ',' && number >= line_number && line_number <= number_b) || (commatilde == '~' && (number == line_number || (line_number - number % number_b) == 0)) )){ strcpy(buffer, string); } if(letter = CMD_INSERT && ( (commatilde == ',' && number >= line_number && line_number <= number_b) || (commatilde == '~' && (number == line_number || (line_number - number % number_b) == 0)) )){ strcat(string, "\n"); strcat(string, buffer); strcpy(buffer, string); } // and then this which is 4 paramters, 1 of which is verified. // this and the one below shouldn't conflict cause of the verification in the same position. }else if(sscanf("%d%c%d%c", &number, &commatilde, &number_b, &letter) == 4 && (commatilde == ',' || commatilde == '~')){ if(letter = CMD_PRINT && ( (commatilde == ',' && number >= line_number && line_number <= number_b) || (commatilde == '~' && (number == line_number || (line_number - number % number_b) == 0)) )){ printf("%s", buffer); } if(letter = CMD_DELETE && ( (commatilde == ',' && number >= line_number && line_number <= number_b) || (commatilde == '~' && (number == line_number || (line_number - number % number_b) == 0)) )){ skip_print = 1; } // and then this which is also 4, 1 of which is verified. // this and the one above shouldn't conflict cause of the verification in the same position. }else if(sscanf("%d%c%c%s", &number, &symbol, &letter, string) == 4 && symbol == '!'){ if(letter == CMD_APPENDS && number != line_number){ strcat(buffer, "\n"); strcat(buffer, string); } if(letter == CMD_REPLACE && number != line_number){ strcpy(buffer, string); } if(letter == CMD_INSERT && number == line_number){ strcat(string, "\n"); strcat(string, buffer); strcpy(buffer, string); } // this one's three paramters, one which we verify. }else if(sscanf("%d%c%c", &number, &symbol, &letter) == 3 && symbol == '!'){ if(letter == CMD_PRINT && number != line_number){ printf("%s", buffer); } if(letter == CMD_DELETE && number != line_number){ skip_print = 1; } // and this one is three, none which we can verify, ergo, less specific. }else if(sscanf("%d%c%s", &number, &letter, string) == 3){ if(letter == CMD_APPENDS && number == line_number){ strcat(buffer, "\n"); strcat(buffer, string); } if(letter == CMD_REPLACE && number == line_number){ strcpy(buffer, string); } if(letter == CMD_INSERT && number == line_number){ strcat(string, "\n"); strcat(string, buffer); strcpy(buffer, string); } // this one is two. check the number is > 0 can be a verification, although // it's not strictly necessary. }else if(sscanf("%d%c", &number, &letter) == 2 && number > 0){ if(letter == CMD_PRINT && number == line_number){ printf("%s", buffer); } if(letter == CMD_QUIT && number == line_number){ program_mode = MODE_END; } if(letter == CMD_DELETE && number == line_number){ skip_print = 1; } // this one is also two, and we can verify the symbol. }else if(sscanf("%c%c", &symbol, &letter) == 2 && symbol == '!'){ if(letter == CMD_PRINT){ // well, if we don't print every line an additional time, // then it just does what it normally does so this doesn't // actually need to do anything? } if(letter = CMD_DELETE){ // likewise, if we don't delete every line, then it acts // normally and again, this doesn't do anything. // I don't actually understand the point in !p and !d. } // and this one is also two, with no verification. }else if(sscanf("%c%s", &letter, string) == 2){ if(letter == CMD_APPENDS){ strcat(buffer, "\n"); strcat(buffer, string); } if(letter == CMD_REPLACE){ strcpy(buffer, string); } if(letter == CMD_INSERT){ strcat(string, "\n"); strcat(string, buffer); strcpy(buffer, string); } // and this one is one paramter, being least specific. }else if(sscanf("%c", &letter) == 1){ if(letter == CMD_PRINT){ printf("%s", buffer); } if(letter == CMD_QUIT){ program_mode = MODE_END; } if(letter == CMD_DELETE){ skip_print = 1; } } if(skip_print == 0){ printf("%s", buffer); } } } } while(program_mode != MODE_END); return 0; }