// Larry Bush April 26, 2002 // // email : bushl2@rpi.edu // Lawrence_Bush@dps.state.ny.us // // Student ID : 660 220 742 // // File Name : grep.cpp // Final Proj. : Grep for Windows // Class : Operating Systems // Instructor : Susan Bonner // Language : C++ // // grep.cpp Initializes the program. // Instantiates variables, checks user input arguments, main program loop. // // /* Project Description This program is something like the grep command in UNIX. It searches through the files in a given directory (including sub-directories) for a word and locates each occurrence of the word. It can also replace each occurrence of that word with another word at the user's request. This program is multi-threaded and preemptable (you can stop a search that is in progress). The program also maintains data integrity at all times by storing a temporary copy of the file that it is doing a search and replace on. It deletes this file after the search file is safely edited and saved. This is an Individual Project (No Partners). There are no known problems with the program. It does everything in the Spec. Program File Description File Purpose ---- ------- grep.cpp Initializes the program. Instantiates variables, checks user input arguments, main program loop. traverse.h Declares the traverse class, which traverses all the subdirectories of a given subdirectory. It also uses the buffer class to process each file that it finds. It performs these tasks on a separate thread from the main program. The traverse class manages its own thread. In other words, the thread is called by a member function of the class. This thread is preemptable. In other words the user may stop the grep process in mid stream. The idea behind this is that the user may have made a mistake and invoked a process that will take a very long time or possibly have unintended (bad) consequences. The traverse class also handles this functionality. traverse.cpp Implementation of traverse member functions. buffer.h Declares and implements the buffer class. The buffer class is called by the traverse function and processes a given file. Processing the file includes opening the file, reading the file into memory (using the line class to store each line), storing a temporary copy of the file to disk, searching the file for a user specified search word (line by line using the line class), replacing the word with the user specified replacement word (if provided), saving the revised file back to disk, closing the file and deleting the temporary file. line.h Declares and implements the line class. The line class is used to store and process a line of the file buffer. Processing a line includes storing the line, providing access functions to the line, provide functions for searching the line for a user specified search word, and replacing the word with the user specified replacement word (if provided). Compiling This program workspace is set up to compile in Visual C++ in Multi-threaded Debug mode. It is also set up to process the first Test Sequence (see below). Running This program is oriented towards UNIX users who wish windows had grep with replacement. Therefore, the user interface accepts commands in a similar way to the UNIX grep. Run from the DOS Prompt: To run the program, the user will type in the command grep (with arguments) at the dos prompt. The program must be in the current directory. The user will input the command line in the following format: grep word_to_find [replacement_word] directory The replacement word is optional. For example, if I want to search for the word school in all the files in my letter folder, I type: grep school C:\Windows\Desktop\Letters Then, if I want to change the word school to college in all my letters that I have written, I could type: grep school college C:\Windows\Desktop\Letters The word to find and the replacement word should each be a single word (no spaces). If you wish to search for or replace with a phrase (with spaces), then it must be enclosed in quotes. You will be allowed to review your request before proceeding. You can also stop a search in progress by typing 'y' and return. For each match found, the program will output: File name The line the word is found on. Run from Visual C++: This program can also be done run through Visual C++ by opening the Project-Settings menu, clicking on the Debug tab, and putting the arguments into the "Program Arguments" box. Note that you leave out the grep command and just input the arguments. */ #include #include #include "traverse.h" //using std::endl; //using std::cout; using namespace std; //******************************************************* //******************************************************* //******** ********* //******** fix_pathname ********* //******** ********* //******************************************************* //******************************************************* // Make an adjustment to the imput path name void fix_pathname( char * currentDirectoryPath ) { strcat(currentDirectoryPath, "\\"); // cat this on in case user doesn't. } //******************************************************* //******************************************************* //******** ********* //******** Main ********* //******** ********* //******************************************************* //******************************************************* // Program start point - main function. // Accept and test user arguments, do a little user i/o, // instantiate and run traverse object. int main(long int argc, char * argv[]) { // input format // grep word_to_find [replacement_word] directory // Check number of user arguments. // Give user instructions if they are incorrect. if(argc > 4) { // arg needs to be 2 or 3 for this (plus program name) std::cerr << "Invalid command line parameters.\n" << "\nToo many arguments. " << "\nUsage: // grep word_to_find [replacement_word] directory" <<"\n\nIf you are running this in VC++, do the following:\n Alt+F7\n Click on Debug Tab (next to general)" <<"\n Type parameters " <<"into Program Arguments text box under project settings.\n"< "; // Wait for 'y' user input before proceeding with directive. // Note this gives the user a chance to abort and check what he input. while(1) { cin>>user_input_character_array; if(strcmp(user_input_character_array, "y") == 0) { break; } if(strcmp(user_input_character_array, "n") == 0) { exit(0); } } // Instantiate traverse object and pass the arguments to it. traverse Directory_Search_Handle(currentDirectoryPath, word_to_find, replacement_word); // Call the thread helper member function. Directory_Search_Handle.multithreaded_traverse(); return 0; // done } // Sample Output // Input // pookator .\files_to_find // This searches a deep directory with many files. // It finds a match to pookator toward the end of the search. // Therefore, this can be used to test the abort command. // To do this, run grep with this command and you will see that // it finds the match. // Then run it again, and abort. (y and return) // you will then see that it stops the search before finding // the match (if you do it quick enough). //Results without abort: /* GREP - SEARCH ONLY ------------------ Search directory: ----------------- .\files_to_find\ Word To Find : pookator Note: You can stop a search in progress by typing 'y' and return. Continue? y/n > y Type y and return to stop search. > MATCH File: Copy of Copy of Copy of longFile.h Line: template Search Completed. Quit? y/n > Results with abort GREP - SEARCH ONLY ------------------ Search directory: ----------------- .\files_to_find\ Word To Find : pookator Note: You can stop a search in progress by typing 'y' and return. Continue? y/n > y Type y and return to stop search. > y Quitting... Error, FindNextFile Failed.Press any key to continue Second Test: searchWord .\files_to_find\layer2 Results: GREP - SEARCH ONLY ------------------ Search directory: ----------------- .\files_to_find\layer2\ Word To Find : searchWord Note: You can stop a search in progress by typing 'y' and return. Continue? y/n > y Type y and return to stop search. > MATCH File: searchfileBottomLevel.h Line: 1111111111111searchWord111111111 MATCH File: searchfile3.h Line: 1111111111111searchWord111111111 MATCH File: searchfile2.h Line: 1111111111111searchWord111111111 MATCH File: searchfile.h Line: 1111111111111searchWord111111111 Search Completed. Quit? y/n > Third Test: searchWord OSisFunFunFun .\files_to_find\layer2 GREP - SEARCH and REPLACE ------------------------- Search directory: ----------------- .\files_to_find\layer2\ Word To Find : searchWord Replacement Word : OSisFunFunFun Note: You can stop a search in progress by typing 'y' and return. Continue? y/n > y Type y and return to stop search. > MATCH File: searchfileBottomLevel.h Old Line: 1111111111111searchWord111111111 New Line: 1111111111111OSisFunFunFun111111111 MATCH File: searchfile3.h Old Line: 1111111111111searchWord111111111 New Line: 1111111111111OSisFunFunFun111111111 MATCH File: searchfile2.h Old Line: 1111111111111searchWord111111111 New Line: 1111111111111OSisFunFunFun111111111 MATCH File: searchfile.h Old Line: 1111111111111searchWord111111111 New Line: 1111111111111OSisFunFunFun111111111 Search Completed. Quit? y/n > Fourth Test: From Root: OSisFunFunFun searchWord C:\WINDOWS\Desktop\Grep12\files_to_find GREP - SEARCH and REPLACE ------------------------- Search directory: ----------------- C:\WINDOWS\Desktop\Grep12\files_to_find\ Word To Find : OSisFunFunFun Replacement Word : searchWord Note: You can stop a search in progress by typing 'y' and return. Continue? y/n > y Type y and return to stop search. > MATCH File: searchfileBottomLevel.h Old Line: 1111111111111OSisFunFunFun111111111 New Line: 1111111111111searchWord111111111 MATCH File: searchfile3.h Old Line: 1111111111111OSisFunFunFun111111111 New Line: 1111111111111searchWord111111111 MATCH File: searchfile2.h Old Line: 1111111111111OSisFunFunFun111111111 New Line: 1111111111111searchWord111111111 MATCH File: searchfile.h Old Line: 1111111111111OSisFunFunFun111111111 New Line: 1111111111111searchWord111111111 Search Completed. Quit? y/n > Test 5: Line: 1111111111111searchWord111111111 MATCH File: searchfile.h Line: 1111111111111searchWord111111111 Search Completed. Quit? y/n > y Quitting... from the dos prompt in the debug folder type: C:\WINDOWS\Desktop\Grep13\Debug>grep searchWord ..\files_to_find\layer2 Results: GREP - SEARCH ONLY ------------------ Search directory: ----------------- ..\files_to_find\layer2\ Word To Find : searchWord Note: You can stop a search in progress by typing 'y' and return. Continue? y/n > y Type y and return to stop search. > MATCH File: searchfileBottomLevel.h Line: 1111111111111searchWord111111111 MATCH File: searchfile3.h Line: 1111111111111searchWord111111111 MATCH File: searchfile2.h Line: 1111111111111searchWord111111111 MATCH File: searchfile.h Line: 1111111111111searchWord111111111 Search Completed. Quit? y/n > y Quitting... C:\WINDOWS\Desktop\Grep13\Debug> */