diff --git a/lib/commandLineParser.cpp b/lib/commandLineParser.cpp index 2e70cca..779e90c 100644 --- a/lib/commandLineParser.cpp +++ b/lib/commandLineParser.cpp @@ -1,25 +1,64 @@ #include "commandLineParser.h" #include +#include // for std::invalid_argument +//implement hashmap for the code CLI::CLI(int argc, char** argv){ - if (argc > 0){ + try{ + if (arc < 2) { + throw std::invalid_argument("Error: No input file provided.\n + Usage: "); + } + //sets program info programName = argv[0]; + inputFile = argv[1] + + //checks that file has correct file extension + if(!(CLI::IsMarkupFile(inputFile))) { + throw std::invalid_argument("Error: Invalid file extension. Expected a '.md' (Markdown) file."); + } + //stores remaining arguments + for (int i = 1; i < argc; i++){ + args.push_back(argv[i]); + } + } + catch (const std::invalid_argument& e) { + std::cerr << e.what() << "\n"; + PrintHelp(); + std::exit(EXIT_FAILURE); + } } - for (int i = 1; i < argc; i++){ - args.push_back(argv[i]); +bool CLI::IsMarkupFile(const std::string& filename) { + //markdown file extension + const std::string requiredExtension = ".md"; + //checks to see if it can even include extension + if (filename.size() <= requiredExtension.size()) { + return false; } + // Extracts the last N characters of the filename (where N is the length of the required extension) + // and checks if they match the required file extension (e.g., ".md"). + // + // Example: + // filename = "notes.md" + // requiredExtension = ".md" + // filename.substr(filename.size() - requiredExtension.size()) == ".md" → true + // + // Reference: https://en.cppreference.com/w/cpp/string/basic_string/substr + return filename.substr(filename.size() - requiredExtension.size()) == requiredExtension; } + +//place to run commands but IDK IF WE SHOULD USE A HASMAP or how we are going to get each method to run void CLI::RunCommands(){ for (int i = 0; i < args.size(); i++){ - + } } void CLI::PrintHelp() const{ std::cout << "Usage:\n" - << " " << programName << " \n" + << " " << programName << " REQUIRED\n" << "Flags:\n" << " --o, --output , optional output filename\n" << " --w, --watch, enables watchdog\n" diff --git a/lib/commandLineParser.h b/lib/commandLineParser.h index 5d595bc..88c9a09 100644 --- a/lib/commandLineParser.h +++ b/lib/commandLineParser.h @@ -60,6 +60,17 @@ public: std::string GetOutputFile() const {return outputFile;} private: + + /** + * @brief Ensures the provided filename has a .markup extension + * + * @param filename The file name to validate + * @return true if file ends with .markup + * @return false otherwise + * @author Preston Shultz (shultzp1@my.erau.edu) + */ + static bool IsMarkupFile(const std::string& filename); + std::string programName; std::vector args; std::string inputFile; diff --git a/lib/watchDog.cpp b/lib/watchDog.cpp index 0b0284c..5894935 100644 --- a/lib/watchDog.cpp +++ b/lib/watchDog.cpp @@ -1,63 +1,77 @@ #include "watchdog.h" namespace fs = std::filesystem; //makes it easier to read - -void Watchdog::Start() +void WatchDog::start() { - //Checks if file exist + //checks if file exist if(!fs::exists(path)) { - //Returns and sets parameters to false if file doesnt exist + //returns and sets parameters to false if file doesnt exist watching = false; - has_initial_time = false; + hasInitialTime = false; std::cout << "WatchDog: File does not exists: " << path << std::endl; return; } - //Grabs intial write time - last_write_time = fs::last_write_time(path); - //Sets watchdog + //grabs intial write time + lastWriteTime = fs::last_write_time(path); watching = true; - has_initial_time = true; + hasInitialTime = true; std::cout << "WatchDog: Started" << std::endl; } - -bool Watchdog::CheckFile(){ +void WatchDog::stop(){ + watching = false; +} +bool WatchDog::checkFile(){ //If not watching returns false if (!watching) return false; //Checking if file was deleted if(!fs::exists(path)) { - if (has_initial_time) { + if (hasInitialTime) { std::cout << "WatchDog: File was delete: " << path << std::endl; - has_initial_time = false; + hasInitialTime = false; return true; } return false; } - //Built in function with file system to check last write time + //Built in function with file system to check last write tim fs::file_time_type currentWriteTime = fs::last_write_time(path); //File was just created - if(!has_initial_time) + if(!hasInitialTime) { - last_write_time = currentWriteTime; - has_initial_time = true; + lastWriteTime = currentWriteTime; + hasInitialTime = true; std::cout << "WatchDog: File created: " << path << std::endl; return true; } //File modified - if (currentWriteTime != last_write_time) + if (currentWriteTime != lastWriteTime) { - last_write_time = currentWriteTime; + lastWriteTime = currentWriteTime; std::cout << "WatchDog: File modifed at " - << TimePointToString(last_write_time) << std::endl; + << timePointToString(lastWriteTime) << std::endl; return true; } - //No change + } catch (const fs::filesystem_error& e) { + // File deleted, inaccessible, or path invalid + if (hasInitialTime) { + std::cout << "WatchDog: File deleted or inaccessible: " << path << std::endl; + hasInitialTime = false; + return true; + } + return false; + + } catch (const std::exception& e) { + std::cerr << "WatchDog: Unexpected error checking file: " << e.what() << std::endl; + return false; + } + + // No change return false; }