Compare commits
10 Commits
1bd489cdc5
...
90f1b0d8dd
Author | SHA1 | Date |
---|---|---|
Nat | 90f1b0d8dd | |
Nat | c062aa8a2e | |
Nat | 7f78f1db3c | |
Nat | 8dd7876ebc | |
Nat | c87debfbae | |
Nat | db0b922e11 | |
Nat | dd9a450042 | |
Nat | 6c402c771f | |
Nat | 02c7492f74 | |
Nat | f4e04b0dfd |
5
Makefile
5
Makefile
|
@ -3,7 +3,10 @@ calathea: calathea.c
|
||||||
if [ ! -d "$(BUILD_DIR)" ]; then\
|
if [ ! -d "$(BUILD_DIR)" ]; then\
|
||||||
mkdir $(BUILD_DIR);\
|
mkdir $(BUILD_DIR);\
|
||||||
fi
|
fi
|
||||||
gcc -Wall -Wextra -pedantic -lm -lcmark calathea.c -o build/calathea
|
gcc calathea.c -Wall -Wextra -pedantic -lm -lcmark -o build/calathea
|
||||||
|
|
||||||
|
install:
|
||||||
|
cp ./build/calathea /usr/bin/calathea
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm build/*
|
rm build/*
|
||||||
|
|
32
README.md
32
README.md
|
@ -1,4 +1,4 @@
|
||||||
# calathea v0.1
|
# calathea v1.0-beta
|
||||||
|
|
||||||
calathea is a small C program used to generate static wikis. It takes a
|
calathea is a small C program used to generate static wikis. It takes a
|
||||||
directory of Common Markdown pages with `[[wikilinks]]` and renders them to
|
directory of Common Markdown pages with `[[wikilinks]]` and renders them to
|
||||||
|
@ -10,10 +10,10 @@ proved to be a serious trial by fire in learning how to effectively work with
|
||||||
zero-terminated strings. There will likely be memoryleaks and comments that
|
zero-terminated strings. There will likely be memoryleaks and comments that
|
||||||
over explain every line of code.
|
over explain every line of code.
|
||||||
|
|
||||||
## Features
|
## features
|
||||||
- [x] Rendering wikilinks
|
- Rendering wikilinks
|
||||||
- [x] Ability to keep track of incoming links
|
- Ability to keep track of incoming links
|
||||||
- [ ] Named wikilinks (i.e. `[[link title|actual page]]`)
|
- Named wikilinks (i.e. `[[link title|actual page]]`)
|
||||||
|
|
||||||
## installation
|
## installation
|
||||||
This tool requires [cmark](https://github.com/commonmark/cmark) to be
|
This tool requires [cmark](https://github.com/commonmark/cmark) to be
|
||||||
|
@ -21,6 +21,7 @@ installed. Once that's set up, clone the repository and run:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ make
|
$ make
|
||||||
|
$ make install
|
||||||
```
|
```
|
||||||
|
|
||||||
If GCC complains it can't find cmark, then try running `ldconfig`. If it
|
If GCC complains it can't find cmark, then try running `ldconfig`. If it
|
||||||
|
@ -28,8 +29,27 @@ still doesn't work, then run `echo $LD_LIBRARY_PATH`. If it doesn't show
|
||||||
anything, you've got to add the right directory to the path, i.e.,
|
anything, you've got to add the right directory to the path, i.e.,
|
||||||
|
|
||||||
```
|
```
|
||||||
$ export $LD_LIBRARY_PATH=/usr/local/lib64
|
$ export LD_LIBRARY_PATH=/usr/local/lib64
|
||||||
```
|
```
|
||||||
|
|
||||||
Or wherever it got installed as per the output of running `make install` for
|
Or wherever it got installed as per the output of running `make install` for
|
||||||
cmark.
|
cmark.
|
||||||
|
|
||||||
|
## usage
|
||||||
|
To see a list of options, run:
|
||||||
|
```
|
||||||
|
$ calathea --help
|
||||||
|
```
|
||||||
|
|
||||||
|
Running calathea builds pages (by default, any filies in `./pages`) to HTML files outputted in the specified output directory (by default, `./build`). To do this, it renders the pages and inserts them into your template file (by default, `./template.html`).
|
||||||
|
|
||||||
|
When building the files, calathea will look for two pseudo-Moustache templates: `{{content}}` and `{{incoming}}`. `{{content}}` will be replaced with the page content and `{{incoming}}` will be replaced with an HTML `ul` list of links to all pages that link to the given page.
|
||||||
|
|
||||||
|
The first line of every file in your pages directory should just be the title of the page. For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
Page Title
|
||||||
|
Here is some page content
|
||||||
|
```
|
||||||
|
|
||||||
|
The content of the above page will be "Here is some page content" and the page title will be "Page Title". You can then link to it from other pages with `[[page title]]`.
|
||||||
|
|
242
calathea.c
242
calathea.c
|
@ -5,8 +5,11 @@
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <argp.h>
|
||||||
#include <cmark.h>
|
#include <cmark.h>
|
||||||
|
|
||||||
|
static const char *VERSION = "1.0.0-beta.1";
|
||||||
|
|
||||||
// Structure defining the content and metadata of a single page
|
// Structure defining the content and metadata of a single page
|
||||||
struct Page {
|
struct Page {
|
||||||
char title[80];
|
char title[80];
|
||||||
|
@ -35,7 +38,7 @@ char * read_file(char *filename) {
|
||||||
rewind(file); // Go back to the beginning of the file
|
rewind(file); // Go back to the beginning of the file
|
||||||
|
|
||||||
// Allocate enough space in our buffer to hold the entire file.
|
// Allocate enough space in our buffer to hold the entire file.
|
||||||
char *buffer = malloc(fileLength);
|
char *buffer = malloc(fileLength + 1);
|
||||||
|
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
printf("Warning: Failed to allocate enough memory for %s\n", filename);
|
printf("Warning: Failed to allocate enough memory for %s\n", filename);
|
||||||
|
@ -44,12 +47,19 @@ char * read_file(char *filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fread(buffer, 1, fileLength, file);
|
fread(buffer, 1, fileLength, file);
|
||||||
|
buffer[fileLength] = 0;
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** Hash map implementation ***/
|
/*** Hash map implementation ***/
|
||||||
|
struct PageMap {
|
||||||
|
struct Page **pages;
|
||||||
|
int capacity;
|
||||||
|
int size;
|
||||||
|
};
|
||||||
|
|
||||||
int helper_hash_polynomial(
|
int helper_hash_polynomial(
|
||||||
char string[],
|
char string[],
|
||||||
int i,
|
int i,
|
||||||
|
@ -65,33 +75,69 @@ int helper_hash_polynomial(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int hash_polynomial(int mapSize, char key[]) {
|
int hash_polynomial(int capacity, char key[]) {
|
||||||
return helper_hash_polynomial(key, 0, strlen(key), mapSize, 0);
|
return helper_hash_polynomial(key, 0, strlen(key), capacity, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void to_lower_case(char dest[], char str[]) {
|
char * to_lower_case(char str[]) {
|
||||||
|
char * lower = malloc((strlen(str) + 1) * sizeof(char));
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; str[i] != '\0'; i++) {
|
for (; str[i] != '\0'; i++) {
|
||||||
dest[i] = tolower(str[i]);
|
lower[i] = tolower(str[i]);
|
||||||
}
|
}
|
||||||
dest[i] = 0;
|
lower[i] = 0;
|
||||||
|
|
||||||
|
return lower;
|
||||||
}
|
}
|
||||||
|
|
||||||
void map_put(struct Page **map, int mapSize, char title[], struct Page *page) {
|
struct PageMap * map(int capacity) {
|
||||||
char lowercased[80];
|
struct PageMap *map = malloc(sizeof(struct PageMap));
|
||||||
to_lower_case(lowercased, title);
|
map->pages = calloc(capacity, sizeof(struct Page *));
|
||||||
|
map->capacity = capacity;
|
||||||
int index = hash_polynomial(mapSize, lowercased);
|
map->size = 0;
|
||||||
map[index] = page;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Page * map_get(struct Page **map, int mapSize, char title[]) {
|
void map_free(struct PageMap *map) {
|
||||||
char lowercased[80];
|
free(map->pages);
|
||||||
to_lower_case(lowercased, title);
|
free(map);
|
||||||
|
}
|
||||||
|
|
||||||
int index = hash_polynomial(mapSize, lowercased);
|
void map_put(struct PageMap *map, char title[], struct Page *page) {
|
||||||
struct Page *page = map[index];
|
char *lowercased = to_lower_case(title);
|
||||||
|
|
||||||
|
int index = hash_polynomial(map->capacity, lowercased);
|
||||||
|
while (map->pages[index] != NULL) index++;
|
||||||
|
map->pages[index] = page;
|
||||||
|
map->size++;
|
||||||
|
|
||||||
|
// Resize the map if we're running low on space
|
||||||
|
if (map->size/map->capacity > 0.75) {
|
||||||
|
map->pages = realloc(map->pages, map->capacity * 2);
|
||||||
|
for (int i = map->capacity; i < map->capacity * 2; i++) {
|
||||||
|
map->pages[i] = 0;
|
||||||
|
}
|
||||||
|
map->capacity *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(lowercased);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Page * map_get(struct PageMap *map, char title[]) {
|
||||||
|
char *lowercased = to_lower_case(title);
|
||||||
|
|
||||||
|
int index = hash_polynomial(map->capacity, lowercased);
|
||||||
|
struct Page *page = map->pages[index];
|
||||||
|
|
||||||
|
char *lowercasedFoundTitle = to_lower_case(page->title);
|
||||||
|
while (strcmp(lowercasedFoundTitle, lowercased) != 0) {
|
||||||
|
page = map->pages[++index];
|
||||||
|
free(lowercasedFoundTitle);
|
||||||
|
lowercasedFoundTitle = to_lower_case(page->title);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(lowercased);
|
||||||
|
free(lowercasedFoundTitle);
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,46 +220,51 @@ char * substitute_string(char dest[], char sub[], char *start, char *end) {
|
||||||
return compiled;
|
return compiled;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
static struct argp_option options[] = {
|
||||||
char pagesLocation[256] = "./pages";
|
{ "src", 's', "dir", 0, "Source directory of pages", 0 },
|
||||||
int mapSize = 1000;
|
{ "version", 'v', 0, 0, "Print the version", 0 },
|
||||||
int initialInboundCapacity = 2;
|
{ "template", 't', "file", 0, "Template file path", 0 },
|
||||||
char templateFileName[256] = "./template.html";
|
{ "output", 'o', "dir", 0, "Output directory", 0 },
|
||||||
char outputDirectoryName[256] = "./build";
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
/*** Argument Parsing ***/
|
static char *pagesLocation = "./pages";
|
||||||
for (int i = 1; i < argc; i++) {
|
static char *templateFileName = "./template.html";
|
||||||
if (strcmp(argv[i], "--pages") == 0) {
|
static char *outputDirectoryName = "./build";
|
||||||
// We only want to do this if a directory was actually supplied
|
|
||||||
if (i + 1 < argc) {
|
static int parse_opt(int key, char *arg, struct argp_state *state) {
|
||||||
i++;
|
// Suppress unused parameter warnings
|
||||||
strcpy(pagesLocation, argv[i]);
|
(void) state;
|
||||||
}
|
|
||||||
} else if (strcmp(argv[i], "--table-size") == 0) {
|
switch (key) {
|
||||||
if (i + 1 < argc) {
|
case 's': {
|
||||||
i++;
|
pagesLocation = arg;
|
||||||
mapSize = atoi(argv[i]);
|
break;
|
||||||
}
|
}
|
||||||
} else if (strcmp(argv[i], "--template") == 0) {
|
case 't': {
|
||||||
if (i + 1 < argc) {
|
templateFileName = arg;
|
||||||
i++;
|
break;
|
||||||
strcpy(templateFileName, argv[i]);
|
}
|
||||||
}
|
case 'o': {
|
||||||
} else if (strcmp(argv[i], "--output-dir") == 0) {
|
outputDirectoryName = arg;
|
||||||
if (i + 1 < argc) {
|
break;
|
||||||
i++;
|
}
|
||||||
strcpy(outputDirectoryName, argv[i]);
|
case 'v': {
|
||||||
}
|
printf("v%s\n", VERSION);
|
||||||
} else if (strcmp(argv[i], "--incoming-cap") == 0) {
|
exit(0);
|
||||||
if (i + 1 < argc) {
|
|
||||||
i++;
|
|
||||||
initialInboundCapacity = atoi(argv[i]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("Unknown argument: %s\n", argv[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int initialInboundCapacity = 2;
|
||||||
|
|
||||||
|
struct argp argp = {options, parse_opt, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
argp_parse(&argp, argc, argv, 0, 0, 0);
|
||||||
|
|
||||||
char *templateContent = read_file(templateFileName);
|
char *templateContent = read_file(templateFileName);
|
||||||
|
|
||||||
if (templateContent == NULL) {
|
if (templateContent == NULL) {
|
||||||
|
@ -230,8 +281,7 @@ int main(int argc, char *argv[]) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Page ** pageMap = malloc(mapSize * sizeof(struct Page *));
|
struct PageMap *pageMap = map(100);
|
||||||
memset(pageMap, 0, mapSize * sizeof(struct Page *));
|
|
||||||
|
|
||||||
// Contains some information about the current file picked from pagesDir
|
// Contains some information about the current file picked from pagesDir
|
||||||
struct dirent *fileEntry = readdir(pagesDir);
|
struct dirent *fileEntry = readdir(pagesDir);
|
||||||
|
@ -300,9 +350,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// Save the content string for later by mallocing it
|
// Save the content string for later by mallocing it
|
||||||
char *contentBuffer = endOfFirstLine;
|
char *contentBuffer = endOfFirstLine;
|
||||||
currentPage->content = malloc(
|
currentPage->content = calloc(strlen(buffer), sizeof(char));
|
||||||
sizeof(char) * (strlen(buffer) - titleLength + 1)
|
|
||||||
);
|
|
||||||
strcpy(currentPage->content, contentBuffer);
|
strcpy(currentPage->content, contentBuffer);
|
||||||
|
|
||||||
// Copy the first line (title) into its respective field
|
// Copy the first line (title) into its respective field
|
||||||
|
@ -310,7 +358,7 @@ int main(int argc, char *argv[]) {
|
||||||
currentPage->title[min(titleLength, 80)] = 0;
|
currentPage->title[min(titleLength, 80)] = 0;
|
||||||
|
|
||||||
// Insert it into the hash map for lookup later
|
// Insert it into the hash map for lookup later
|
||||||
map_put(pageMap, mapSize, currentPage->title, currentPage);
|
map_put(pageMap, currentPage->title, currentPage);
|
||||||
|
|
||||||
// Get ready to process the next page
|
// Get ready to process the next page
|
||||||
fileEntry = readdir(pagesDir);
|
fileEntry = readdir(pagesDir);
|
||||||
|
@ -329,7 +377,7 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the directory if it doesn't exist
|
// Create the directory if it doesn't exist
|
||||||
char *createOutputDir = concat_strings(2, "mkdir ", outputDirectoryName);
|
char *createOutputDir = concat_strings(3, "mkdir ", outputDirectoryName, " 2> /dev/null");
|
||||||
system(createOutputDir);
|
system(createOutputDir);
|
||||||
free(createOutputDir);
|
free(createOutputDir);
|
||||||
|
|
||||||
|
@ -350,13 +398,23 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
int linkLength = nextLinkEnd - nextLinkStart;
|
int linkLength = nextLinkEnd - nextLinkStart;
|
||||||
|
|
||||||
// Determine the exact title of the link
|
char *nextVerticalBar = strchr(nextLinkStart, '|');
|
||||||
char title[linkLength - 3];
|
|
||||||
|
|
||||||
strncpy(title, nextLinkStart + 2, (linkLength - 2)*sizeof(char));
|
char *linkTitle = calloc(linkLength - 3, sizeof(char));
|
||||||
title[linkLength - 2] = 0;
|
char *linkPageTitle = NULL;
|
||||||
|
|
||||||
struct Page *linkedPage = map_get(pageMap, mapSize, title);
|
if (nextVerticalBar != NULL && nextVerticalBar < nextLinkEnd) {
|
||||||
|
// The link is in the from [[link title|page title]]
|
||||||
|
strncpy(linkTitle, nextLinkStart + 2, (nextVerticalBar - 1) - (nextLinkStart + 1));
|
||||||
|
linkPageTitle = calloc((nextLinkEnd - 2) - nextVerticalBar, sizeof(char));
|
||||||
|
strncpy(linkPageTitle, nextVerticalBar + 1, (nextLinkEnd - 1) - nextVerticalBar);
|
||||||
|
} else {
|
||||||
|
// The link is of the form [[page title]]
|
||||||
|
linkPageTitle = linkTitle;
|
||||||
|
strncpy(linkTitle, nextLinkStart + 2, (linkLength - 2)*sizeof(char));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Page *linkedPage = map_get(pageMap, linkPageTitle);
|
||||||
|
|
||||||
char *compiledLink = NULL;
|
char *compiledLink = NULL;
|
||||||
|
|
||||||
|
@ -364,12 +422,12 @@ int main(int argc, char *argv[]) {
|
||||||
// i.e. the page does not exist
|
// i.e. the page does not exist
|
||||||
compiledLink = concat_strings(3,
|
compiledLink = concat_strings(3,
|
||||||
"<a class=\"calathea-404\" href=\"#\">",
|
"<a class=\"calathea-404\" href=\"#\">",
|
||||||
title,
|
linkTitle,
|
||||||
"</a>"
|
"</a>"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
page_list_insert(linkedPage->incoming, currentPage);
|
page_list_insert(linkedPage->incoming, currentPage);
|
||||||
compiledLink = concat_strings(5, "[", title, "](", linkedPage->permalink, ")");
|
compiledLink = concat_strings(5, "[", linkTitle, "](", linkedPage->permalink, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
char *newContent = substitute_string(
|
char *newContent = substitute_string(
|
||||||
|
@ -378,6 +436,10 @@ int main(int argc, char *argv[]) {
|
||||||
currentPage->content = newContent;
|
currentPage->content = newContent;
|
||||||
|
|
||||||
free(compiledLink);
|
free(compiledLink);
|
||||||
|
if (linkTitle != linkPageTitle) {
|
||||||
|
free(linkPageTitle);
|
||||||
|
}
|
||||||
|
free(linkTitle);
|
||||||
|
|
||||||
// Move to the next chunk of the file
|
// Move to the next chunk of the file
|
||||||
// NOTE: This is suboptimal, because we search for "[[" from the
|
// NOTE: This is suboptimal, because we search for "[[" from the
|
||||||
|
@ -416,28 +478,38 @@ int main(int argc, char *argv[]) {
|
||||||
char *incomingTagStart = strstr(renderedPage, "{{incoming}}");
|
char *incomingTagStart = strstr(renderedPage, "{{incoming}}");
|
||||||
if (incomingTagStart != NULL) {
|
if (incomingTagStart != NULL) {
|
||||||
// Build the incoming links list
|
// Build the incoming links list
|
||||||
int incomingListSize = 37; // <ul class="calathea-incoming">\n</ul>\n
|
// <ul class="calathea-incoming">\n</ul>\n
|
||||||
for (int i = 0; i < currentPage->incoming->length; i++) {
|
int incomingListSize = 37;
|
||||||
// ` <li><a href=\"[permalink]\">[title]</a></li>\n`
|
if (currentPage->incoming->length == 0) {
|
||||||
struct Page *page = currentPage->incoming->pages[i];
|
// ` <li>none</li>\n`
|
||||||
incomingListSize += 27 + strlen(page->title) + strlen(page->permalink);
|
incomingListSize += 16;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < currentPage->incoming->length; i++) {
|
||||||
|
// ` <li><a href=\"[permalink]\">[title]</a></li>\n`
|
||||||
|
struct Page *page = currentPage->incoming->pages[i];
|
||||||
|
incomingListSize += 27 + strlen(page->title) + strlen(page->permalink);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *incomingLinksList = malloc((incomingListSize + 1) * sizeof(char));
|
char *incomingLinksList = malloc((incomingListSize + 1) * sizeof(char));
|
||||||
memset(incomingLinksList, 0, (incomingListSize + 1) * sizeof(char));
|
memset(incomingLinksList, 0, (incomingListSize + 1) * sizeof(char));
|
||||||
|
|
||||||
strcpy(incomingLinksList, "<ul class=\"calathea-incoming\">\n");
|
strcpy(incomingLinksList, "<ul class=\"calathea-incoming\">\n");
|
||||||
for (int i = 0; i < currentPage->incoming->length; i++) {
|
if (currentPage->incoming->length == 0) {
|
||||||
struct Page *page = currentPage->incoming->pages[i];
|
strcat(incomingLinksList, " <li>none</li>\n");
|
||||||
char *link = concat_strings(5,
|
} else {
|
||||||
" <li><a href=\"",
|
for (int i = 0; i < currentPage->incoming->length; i++) {
|
||||||
page->permalink,
|
struct Page *page = currentPage->incoming->pages[i];
|
||||||
"\">",
|
char *link = concat_strings(5,
|
||||||
page->title,
|
" <li><a href=\"",
|
||||||
"</a></li>\n"
|
page->permalink,
|
||||||
);
|
"\">",
|
||||||
strcat(incomingLinksList, link);
|
page->title,
|
||||||
free(link);
|
"</a></li>\n"
|
||||||
|
);
|
||||||
|
strcat(incomingLinksList, link);
|
||||||
|
free(link);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
strcat(incomingLinksList, "</ul>\n");
|
strcat(incomingLinksList, "</ul>\n");
|
||||||
|
|
||||||
|
@ -471,6 +543,7 @@ int main(int argc, char *argv[]) {
|
||||||
currentPage = currentPage->next;
|
currentPage = currentPage->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Pages built successfully in %s\n", outputDirectoryName);
|
||||||
|
|
||||||
/*** Deallocation and whatnot ***/
|
/*** Deallocation and whatnot ***/
|
||||||
currentPage = firstPage;
|
currentPage = firstPage;
|
||||||
|
@ -484,8 +557,7 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
closedir(pagesDir);
|
closedir(pagesDir);
|
||||||
free(templateContent);
|
free(templateContent);
|
||||||
|
map_free(pageMap);
|
||||||
// Deallocate all the pages
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue