From 408fd5fc2eb70d09d7772cb7114bff7a7905f36b Mon Sep 17 00:00:00 2001
From: Hayden Hargreaves
Date: Wed, 29 Oct 2025 15:09:45 -0700
Subject: [PATCH] (FEAT): Completed watchdog v2 updates.
This works the way expected, all thats left is the CLI and the command
arg parser.
---
input.md | 22 --------
lib/commandLineParser.cpp | 17 ++++---
lib/commandLineParser.h | 103 +++++++++++++++++++-------------------
lib/documentConverter.h | 33 ++++++++++++
lib/fileSystem.cpp | 1 +
lib/parser.cpp | 6 ++-
lib/watchdog.cpp | 22 ++++----
lib/watchdog.h | 13 +++--
src/main.cpp | 10 +++-
syntax.md | 45 -----------------
test/input.html | 25 +++++++++
test/input.md | 39 ++++++++++++---
12 files changed, 188 insertions(+), 148 deletions(-)
delete mode 100644 input.md
create mode 100644 lib/documentConverter.h
delete mode 100644 syntax.md
create mode 100644 test/input.html
diff --git a/input.md b/input.md
deleted file mode 100644
index f66ff5f..0000000
--- a/input.md
+++ /dev/null
@@ -1,22 +0,0 @@
-hello `world`
-
-
-This `is also a code block`
-
-hi `mom
-hello`
-
-hi `mom
-
-this is too far`
-
-
-*this is **words***
-
-## **Hello world**
-
-### hello *world*
-
-# ***This is both!***
-
-###### This is neither
diff --git a/lib/commandLineParser.cpp b/lib/commandLineParser.cpp
index a2b6a14..2a1c4fc 100644
--- a/lib/commandLineParser.cpp
+++ b/lib/commandLineParser.cpp
@@ -10,11 +10,11 @@ CLI::CLI(int argc, char **argv) {
"Error: No input file provided.\nUsage: ");
}
// sets program info
- programName = argv[0];
- inputFile = argv[1];
+ program_name = argv[0];
+ input_file = argv[1];
// checks that file has correct file extension
- if (!(CLI::IsMarkupFile(inputFile))) {
+ if (!(CLI::IsMarkupFile(input_file))) {
throw std::invalid_argument(
"Error: Invalid file extension. Expected a '.md' (Markdown) file.");
}
@@ -54,15 +54,16 @@ bool CLI::IsMarkupFile(const std::string &filename) {
// 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++) {
+ for (size_t i = 0; i < args.size(); i++) {
}
}
void CLI::PrintHelp() const {
std::cout << "Usage:\n"
- << " " << programName << " REQUIRED\n"
+ << "\t" << program_name << " \n"
<< "Flags:\n"
- << " --o, --output , optional output filename\n"
- << " --w, --watch, enables watchdog\n"
- << " --s, --stop, stops watchdog\n";
+ << "\t-o, --output , optional output filename\n"
+ << "\t-w, --watch, enables watchdog\n";
}
+
+// ./parser input_file -w dhuahdakhk -o output
diff --git a/lib/commandLineParser.h b/lib/commandLineParser.h
index 88c9a09..55ad1fd 100644
--- a/lib/commandLineParser.h
+++ b/lib/commandLineParser.h
@@ -1,9 +1,9 @@
-/**
+/**
* @file commandLineParser.h
* @brief Parses command line
* @author Preston Shultz
- * Sources:
- *
+ * Sources:
+ *
*/
#ifndef COMMAND_LINE_PARSER_H
@@ -17,64 +17,63 @@
*
* Parse input arguments, sets input and output files
* Lets user use commands with program
- *
+ *
* @author Preston Shultz (shultzp1@my.erau.edu)
*/
-class CLI{
+class CLI {
public:
- /**
- * @brief Takes in argc and argv and converts it to vector
- *
- * CLI constructor
- *
- * @author Preston Shultz (shultzp1@my.erau.edu)
- */
- CLI(int argc, char **argv);
+ /**
+ * @brief Takes in argc and argv and converts it to vector
+ *
+ * CLI constructor
+ *
+ * @author Preston Shultz (shultzp1@my.erau.edu)
+ */
+ CLI(int argc, char **argv);
- /**
- * @brief Runs Commands
- *
- * @author Preston Shultz (shultzp1@my.erau.edu)
- */
- void RunCommands();
+ /**
+ * @brief Runs Commands
+ *
+ * @author Preston Shultz (shultzp1@my.erau.edu)
+ */
+ void RunCommands();
- /**
- * @brief Prints a list of commands that can be used
- *
- * @author Preston Shultz (shultzp1@my.erau.edu)
- */
- void PrintHelp() const;
+ /**
+ * @brief Prints a list of commands that can be used
+ *
+ * @author Preston Shultz (shultzp1@my.erau.edu)
+ */
+ void PrintHelp() const;
- /**
- * @brief Returns input file
- *
- * @author Preston Shultz (shultzp1@my.erau.edu)
- */
- std::string GetInputFile() const {return inputFile;}
+ /**
+ * @brief Returns input file
+ *
+ * @author Preston Shultz (shultzp1@my.erau.edu)
+ */
+ std::string GetInputFile() const { return input_file; }
- /**
- * @brief Returns output file
- *
- * @author Preston Shultz (shultzp1@my.erau.edu)
- */
- std::string GetOutputFile() const {return outputFile;}
+ /**
+ * @brief Returns output file
+ *
+ * @author Preston Shultz (shultzp1@my.erau.edu)
+ */
+ std::string GetOutputFile() const { return output_file; }
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);
- /**
- * @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;
- std::string outputFile;
+ std::string program_name;
+ std::vector args;
+ std::string input_file;
+ std::string output_file;
};
-#endif
\ No newline at end of file
+#endif
diff --git a/lib/documentConverter.h b/lib/documentConverter.h
new file mode 100644
index 0000000..29ce2f4
--- /dev/null
+++ b/lib/documentConverter.h
@@ -0,0 +1,33 @@
+#ifndef DOCUMENT_CONVERTER_H
+#define DOCUMENT_CONVERTER_H
+
+#include "parser.h"
+#include "watchdog.h"
+#include
+
+class DocumentConverter {
+private:
+ Parser parser;
+ Watchdog watchdog;
+
+public:
+ DocumentConverter(std::string input, std::string output = "")
+ : parser(input, output), watchdog(input) {};
+
+ void Convert() {
+ this->parser.ParseDocument();
+ this->parser.WriteOutput();
+ }
+
+ void ConvertWatcher() {
+ // This is a lambda, which can be passed into the start function of
+ // watchdog.
+ std::function callback = [this]() {
+ this->parser.ParseDocument();
+ this->parser.WriteOutput();
+ };
+ this->watchdog.Start(callback);
+ }
+};
+
+#endif
diff --git a/lib/fileSystem.cpp b/lib/fileSystem.cpp
index 3742b7a..87f2ebe 100644
--- a/lib/fileSystem.cpp
+++ b/lib/fileSystem.cpp
@@ -2,6 +2,7 @@
#include "util.h"
#include
+#include
#include
#include
#include
diff --git a/lib/parser.cpp b/lib/parser.cpp
index 1d5a7e5..d1674d6 100644
--- a/lib/parser.cpp
+++ b/lib/parser.cpp
@@ -11,7 +11,8 @@ using std::string;
using std::vector;
void Parser::Inspect() {
- std::cerr << "Parser::Inspect() is not yet implemented." << std::endl;
+ std::cout << this->position << std::endl;
+ std::cout << this->content.size() << std::endl;
}
void Parser::NormalizeInputStream() {
@@ -40,6 +41,9 @@ void Parser::WriteOutput() {
}
void Parser::ParseDocument() {
+ // NOTE:This needs to be set so the parsing can continue
+ this->position = 0;
+
try {
this->content = this->filesystem.ReadInputFile();
} catch (const std::runtime_error &e) {
diff --git a/lib/watchdog.cpp b/lib/watchdog.cpp
index 06f3eac..700edc5 100644
--- a/lib/watchdog.cpp
+++ b/lib/watchdog.cpp
@@ -6,19 +6,19 @@
namespace fs = std::filesystem;
using namespace std::chrono;
-void Watchdog::Start() {
+void Watchdog::Start(std::function callback) {
// checks if file exist
if (!fs::exists(this->path))
throw std::runtime_error("File does not exist.");
// Loop forever and check the file.
while (true) {
- CheckFile();
+ CheckFile(callback);
std::this_thread::sleep_for(this->POLLING_INTERVAL);
}
}
-void Watchdog::CheckFile() {
+void Watchdog::CheckFile(std::function callback) {
// LONG STORY SHORT:
// When a file is written to, it aquires an OS lock, which means our program
// cannot access it. So when we request, it fails. So we should basically just
@@ -41,16 +41,20 @@ void Watchdog::CheckFile() {
this->last_write_time = currentWriteTime;
time_point before = high_resolution_clock::now();
-
- // DO SOMETHING
- std::this_thread::sleep_for(this->POLLING_INTERVAL);
-
+ callback();
time_point after = high_resolution_clock::now();
duration dur = after - before;
long ms = std::chrono::duration_cast(dur).count();
- std::cout << std::endl
- << "Recompiled in \033[36m" << ms << "ms\033[0m" << std::endl;
+ long us = std::chrono::duration_cast(dur).count();
+
+ if (ms > 0) {
+ std::cout << std::endl
+ << "Recompiled in \033[36m" << ms << "ms\033[0m" << std::endl;
+ } else {
+ std::cout << std::endl
+ << "Recompiled in \033[36m" << us << "μs\033[0m" << std::endl;
+ }
}
} catch (const std::exception &ex) {
// On last attempt, bubble the error outward
diff --git a/lib/watchdog.h b/lib/watchdog.h
index 32b0aef..dd34483 100644
--- a/lib/watchdog.h
+++ b/lib/watchdog.h
@@ -15,7 +15,8 @@
#include //makes timestamps easier
#include //Convert time_t to std::tm for local time
#include //allow access to files platform independent
-#include //Formats std::tim into "YYYY-MM-DD HH-MM-SS"
+#include
+#include //Formats std::tim into "YYYY-MM-DD HH-MM-SS"
#include
#include
@@ -33,10 +34,13 @@ protected:
*
* Checks if a file has been modified
*
+ * @param callback Callback function to execute when the watchdog notices a
+ * change.
+ *
* @author Preston Shultz (shultzp1@my.erau.edu)
* @author Hayden Hargreaves (hhargreaves2006@gmail.com)
*/
- void CheckFile();
+ void CheckFile(std::function callback);
public:
Watchdog(const std::string &path) : path(path) {}
@@ -46,9 +50,12 @@ public:
*
* Starts the watchdog to check of a file is modified
*
+ * @param callback Callback function to execute when the watchdog notices a
+ * change.
+ *
* @author Preston Shultz (shultzp1@my.erau.edu)
*/
- void Start();
+ void Start(std::function callback);
/**
* @brief watchdog class.
diff --git a/src/main.cpp b/src/main.cpp
index 922ba50..3c8a116 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,3 +1,4 @@
+#include "../lib/documentConverter.h"
#include "../lib/inlineNode.h"
#include "../lib/parser.h"
#include "../lib/structureNode.h"
@@ -40,7 +41,7 @@ void test_nodes() {
*/
void test_watchdog() {
Watchdog wd("test/input.md");
- wd.Start();
+ wd.Start(nullptr);
}
void test_input(int argc, char **argv) {
@@ -66,4 +67,9 @@ void test_input(int argc, char **argv) {
std::cout << std::endl;
}
-int main(int argc, char **argv) { test_watchdog(); }
+void test_document_converter() {
+ DocumentConverter dc("test/input.md");
+ dc.Convert();
+}
+
+int main(int argc, char **argv) { test_document_converter(); }
diff --git a/syntax.md b/syntax.md
deleted file mode 100644
index bd80e12..0000000
--- a/syntax.md
+++ /dev/null
@@ -1,45 +0,0 @@
-
-Reference [here](https://www.markdownguide.org/basic-syntax/)
-
-Headings, h# tags
-
-
-# Header Level 1 -> Content
-## Header Level 2 -> Content
-### Header Level 3 -> Content
-#### Header Level 4 -> Content
-##### Header Level 5 -> Content
-###### Header Level 6 -> Content
-
-
-Alternate syntax (n number of =/-)
-
-Header Level 1 -> Content
-================
-
-
-Header Level 2 -> Content
-----------------
-
-
-Paragraph tags
-
-Hello world -> Hello world
-
-This is also
-a paragraph -> this is also a paragraph regardless
-regardless
-
-However
-this is a break, because it ends with two spaces -> However
this is a break, because it ends with two spaces
-
-Double returns also
-
-yields new paragraphs -> Double returns also
yields new paragraphs
-
-
-*italic* -> italic
-**bold** -> bold
-***italic bold*** -> italic bold
-
-hello **world** -> [TextClass: hello, BoldClass: world]
diff --git a/test/input.html b/test/input.html
new file mode 100644
index 0000000..d5b4d49
--- /dev/null
+++ b/test/input.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+ Document
+
+
+Reference [here](https://www.markdownguide.org/basic-syntax/)
+Headings, h# tags
+Header Level 1 -> Content
## Header Level 2 -> Content
### Header Level 3 -> Content
#### Header Level 4 -> Content
##### Header Level 5 -> Content
###### Header Level 6 -> Content
+Alternate syntax (n number of =/-)
+Header Level 1 ->
Content
================
+Header Level 2 ->
Content
----------------
+Paragraph tags
+Hello world ->
Hello world
+This is also a paragraph ->
this is also a paragraph regardless
regardless
+However this is a break, because it ends with two spaces ->
However
this is a break, because it ends with two spaces
+Double returns also
+yields new paragraphs ->
Double returns also
yields new paragraphs
+italic -> italic bold -> bold italic bold -> italic bold
+hello world -> [TextClass: hello, BoldClass: world]
+
+
+
\ No newline at end of file
diff --git a/test/input.md b/test/input.md
index 54ed126..2ba0eb3 100644
--- a/test/input.md
+++ b/test/input.md
@@ -1,17 +1,44 @@
+Reference [here](https://www.markdownguide.org/basic-syntax/)
+
+Headings, h# tags
-# Hello world in an h1 tag
+# Header Level 1 -> Content
+## Header Level 2 -> Content
+### Header Level 3 -> Content
+#### Header Level 4 -> Content
+##### Header Level 5 -> Content
+###### Header Level 6 -> Content
-## This is a h2 tag
+Alternate syntax (n number of =/-)
+
+Header Level 1 -> Content
+================
-### h3
+Header Level 2 -> Content
+----------------
-#### h4
+Paragraph tags
-##### h5
+Hello world -> Hello world
-###### h6
+This is also
+a paragraph -> this is also a paragraph regardless
+regardless
+However
+this is a break, because it ends with two spaces -> However
this is a break, because it ends with two spaces
+
+Double returns also
+
+yields new paragraphs -> Double returns also
yields new paragraphs
+
+
+*italic* -> italic
+**bold** -> bold
+***italic bold*** -> italic bold
+
+hello **world** -> [TextClass: hello, BoldClass: world]