From 476aec573401085b2b91c864d2da97a9b6191a48 Mon Sep 17 00:00:00 2001 From: John Breaux Date: Sun, 17 Apr 2022 22:03:17 -0500 Subject: [PATCH] C++-ify it some more, begin readfile --- .gitignore | 3 ++ Makefile | 2 +- inc/graph.hpp | 76 +++++++++++++--------------------------------- inc/read_input.hpp | 2 +- src/graph.cpp | 57 ++++++++++++++++++++++++++++------ src/main.cpp | 12 ++++---- src/read_input.cpp | 67 +++++++++++++++++++++++++--------------- 7 files changed, 122 insertions(+), 97 deletions(-) diff --git a/.gitignore b/.gitignore index 9480b49..9ce242f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,9 @@ # Local History for Visual Studio Code .history/ +# ---> Input files +*input*.txt + # ---> C # Prerequisites *.d diff --git a/Makefile b/Makefile index 3ecd532..8a57c67 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ VPATH = $(SPATH) $(IPATH) $(DPATH) $(OPATH) # compiler and compiler flags CC = g++ -CFLAGS = -I$(IPATH) -pthread -lrt +CFLAGS = -I$(IPATH) -pthread -lrt -std=c++11 # list of object files SOURCES = $(wildcard $(SPATH)/*.$(STYPE)) diff --git a/inc/graph.hpp b/inc/graph.hpp index 90648f4..c915ab5 100644 --- a/inc/graph.hpp +++ b/inc/graph.hpp @@ -1,57 +1,23 @@ -// Gee, ain't pointers just the greatest? -//? Rename to'graph'? Typedef to 'graph'? -struct adjmatrix { - int num_processes; // The number of processes in the matrix - int num_resources; // The number of resources in the matrix - int *resource_counts; // The counts of each resource in the matrix - int **matrix; // Tell me, Mr. Anderson, what good is a phone call if you are unable to speak? -}; +class graph { +private: + int num_processes; + int num_resources; + int *resource_counts; + struct m{ + int x, y; + int **data; + } matrix; // Tell me, Mr. Anderson, what good is a phone call if you are unable to speak? -/* graph_reduce: - Perform the graph reduction algorithm on the adjacency matrix to detect deadlocks - This algorithm is described in section 5.2 of the Zybook - (!THIS MODIFIES THE GRAPH!) - @params: - graph: adjacency matrix containing all relevant information about the graph - @returns: - int: - 1 if graph is not reducible (deadlock) - 0 if graph is reducible (no deadlock) -*/ -int graph_reduce(struct adjmatrix *graph); - -/* knot_detect: - Perform the knot detection algorithm on the adjacency matrix to detect deadlocks - (!THIS MODIFIES THE GRAPH!) - @params: - graph: adjacency matrix containing all relevant information about the graph - @returns: - int: - 1 if graph is knotted (deadlock) - 0 if graph is not (no deadlock) -*/ -int knot_detect(struct adjmatrix *graph); - -/* create_adjmatrix: - Create a new adjmatrix (!THIS INVOLVES MEMORY ALLOCATION!) (Basically a constructor) - @params: - num_processes - num_resources - @returns: - struct adjmatrix: - Empty adjacency matrix of size (num_processes+num_resources)^2 - Fill in the blanks yourself -*/ -struct adjmatrix * create_adjmatrix(int num_processes, int num_resources); - -/* destroy_adjmatrix: - Destroy an adjmatrix (!THIS INVOLVES MEMORY DEALLOCATION!) (Basically a destructor) - @params: - matrix: - A structure containing all relevant information about the graph - @returns: - int: - 0 if operation completed successfully, else a value of type `errno` -*/ -int destroy_adjmatrix(struct adjmatrix *matrix); +public: + // Constructors + graph(const int processes, const int resources); + // Destructors + ~graph(); + // Initializers: + void init(const int **data); + // check functions: + // is the graph... + bool reducible();// ? + bool knotted();// ? +}; \ No newline at end of file diff --git a/inc/read_input.hpp b/inc/read_input.hpp index 8f7f291..b72931f 100644 --- a/inc/read_input.hpp +++ b/inc/read_input.hpp @@ -1,3 +1,3 @@ -int read_file(char *filename, struct adjmatrix *graph); \ No newline at end of file +void read_file(std::string filename); \ No newline at end of file diff --git a/src/graph.cpp b/src/graph.cpp index 1ff8da7..134408e 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -1,22 +1,59 @@ #include #include "graph.hpp" -int graph_reduce(struct adjmatrix *graph) { +/* reducible: + Perform the graph reduction algorithm on the adjacency matrix to detect deadlocks + This algorithm is described in section 5.2 of the Zybook + (!THIS MODIFIES THE GRAPH!) + @params: none, uses class-internal data + @returns: + bool: + false if graph is not reducible (deadlock) + true if graph is reducible (no deadlock) +*/ +bool graph::reducible() { // TODO: Implement a function which checks if a process is blocked // TODO: Use that function to implement the graph reduction algorithm //? Make sure when reducing the graph, you don't try to delete the - return 0; + return false; } -int knot_detect(struct adjmatrix *graph) { - return 0; +/* knotted: + Perform the knot detection algorithm on the adjacency matrix to detect deadlocks + (!THIS MODIFIES THE GRAPH!) + @params: none, uses class-internal data + @returns: + int: + true if graph is knotted (deadlock) + false if graph is not (no deadlock) +*/ +bool graph::knotted() { + return false; } -int destroy_adjmatrix(struct adjmatrix *matrix) { - for (int i = 0; i < matrix->num_processes + matrix->num_resources; i++) { - free(matrix->matrix[i]); +graph::graph (const int processes, const int resources) { + num_processes = processes; + num_resources = resources; + matrix.x = processes + resources; + matrix.y = matrix.x; + matrix.data = new int*[matrix.x]; + for (int x = 0; x < matrix.x; x++) { + matrix.data[x] = new int[matrix.y]; } - free(matrix->matrix); - free(matrix->resource_counts); - return 0; +} + +graph::~graph() { + /* clean up the 2D matrix */ + if (matrix.data) { + if (matrix.x || matrix.y) { + // delete y axes + for (int x = 0; x < matrix.x; x++) { + delete matrix.data[x]; + } + // delete x axis + delete matrix.data; + matrix.x = 0; matrix.y = 0; + } + } + free(resource_counts); } diff --git a/src/main.cpp b/src/main.cpp index 25be347..ebbf572 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,10 @@ /* +-------------+---------+-----------------------+ - | John Breaux | jab0910 | JohnBreaux@my.unt.edu | //TODO put your name here + | John Breaux | jab0910 | JohnBreaux@my.unt.edu | + | | | | //TODO put your names here +-------------+---------+-----------------------+ | Created 2022-04-16 | +-----------------------------------------------+ */ -#include // printf +#include #include "graph.hpp" // Graph reduction/Knot detection, struct adjmatrix #include "read_input.hpp" //TODO: Read input in the associated C file, and provide an interface to that function here @@ -12,16 +13,15 @@ int main(int argc, char** argv) { // TODO: Grab file name from args //? Command line argument structure? //? Other flags? What other features should this have? - char* filename = NULL; + if (argc < 2) return 1; + std::string filename = argv[1]; //TODO: Implement reading from a file - struct adjmatrix *graph; - read_file(filename, graph); + read_file(filename); // TODO: Implement graph reduction and/or knot detection // TODO: Destroy the graph created by read_file - destroy_adjmatrix(graph); return 0; } \ No newline at end of file diff --git a/src/read_input.cpp b/src/read_input.cpp index 7d0b1d8..75c4084 100644 --- a/src/read_input.cpp +++ b/src/read_input.cpp @@ -1,39 +1,58 @@ //TODO: Include C file IO header (stdio.h? Whatever it is) -#include +#include +#include +#include +#include +#include #include "graph.hpp" // struct adjmatrix #include "read_input.hpp" // read_input #define MAX_LINE_LEN 1024 +// Vector of regices +std::vector patterns = { + //* A line starting with a % is a comment, and should be skipped + //* A blank line should be skipped + //* A line starting with `num_processes=` contains the number of processes + std::regex("^.*(num_processes)\\s*=\\s*(\\d+).*"), + //* A line starting with `num_resources=` contains the number of resources + std::regex("^.*(num_resources)\\s*=\\s*(\\d+)"), + //* A line containing comma-separated values should be returned as-is, for manual disassembly + std::regex("^([0-9, ]+)") +}; + // TODO: Implement reading from a file -int read_file(char *filename, struct adjmatrix *graph) { - // TODO: Open file with name filename as read-only - FILE *f = fopen(filename, "r"); +void read_file(std::string filename) { + // Open file with name filename as read-only + std::fstream f; f.open(filename, f.in); // TODO: Check for file IO errors (I might have a solution for that in another project) int num_processes = 0, num_resources = 0; - char line[MAX_LINE_LEN]; // Lines can be no more than 1KB in size, a sensible limitation - while (!feof(f)) { - //* A line starting with a % is a comment, and should be skipped - // if %: - continue; - //* A blank line should be skipped - // if blank: - continue; - //* A line starting with `num_processes=` contains the number of processes - //if "num_processes": - num_processes = 0; // TODO: Read file - //* A line starting with `num_resources=` contains the number of resources - //if "num_resources": - num_resources = 0; - // TODO: create graph 'object' here - //* A line containing num_resources numbers follows, indicating the number of each resource - //* Resources are comma-separated, so there can never be more than 1/2 as many as max line length - int resource_counts[MAX_LINE_LEN/2]; - //* A comma-separated, newline-separated adjacency matrix with which to reduce + std::vector rescount; + std::vector> matrix; + std::string line; // Lines can be no more than 1KB in size, a sensible limitation + while (!f.eof()) { + std::getline (f, line); + std::smatch res; + // Iterate over each pattern, and grab the associated data + for (auto pattern: patterns) { + if (std::regex_search (line, res, pattern)) { + // get the pattern type, value + std::string type = res.format("$1"), value = res.format("$2"); + // Handle the pattern + if (type == "num_processes") { num_processes = std::stoi(value); } else + if (type == "num_resources") { num_resources = std::stoi(value); } else + if (type.length()/2 <= num_resources) { + // This is the resource count structure + } + break; + } + } } - // TODO: Close file + // Close file + f.close(); // TODO: Check for file IO errors (Shouldn't be any) + return; }