aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaghuram Subramani <raghus2247@gmail.com>2025-06-19 11:53:16 +0530
committerRaghuram Subramani <raghus2247@gmail.com>2025-06-19 11:53:16 +0530
commit7698d438f594665661edf90964f92591b7a29556 (patch)
tree7c92c3ff429c15a1b97ec13c125f1f32e8613f76
parentbfdbb1e1316225f5bff0309a1b9008dcff567cf5 (diff)
(misc): modularize program
-rw-r--r--CMakeLists.txt5
-rw-r--r--include/copy.h12
-rw-r--r--include/engine.h6
-rw-r--r--include/filehandler.h4
-rw-r--r--include/lexer.h19
-rw-r--r--include/template.h6
-rw-r--r--src/copy.c48
-rw-r--r--src/engine.c52
-rw-r--r--src/lexer.c81
-rw-r--r--src/main.c193
-rw-r--r--src/template.c28
11 files changed, 266 insertions, 188 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2b1f6cd..3d03bba 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,8 +2,12 @@ cmake_minimum_required(VERSION 3.21)
project(msg C)
set(SRC
+ src/copy.c
+ src/engine.c
src/filehandler.c
+ src/lexer.c
src/main.c
+ src/template.c
)
add_executable(msg ${SRC})
@@ -23,6 +27,7 @@ set(C_COMPILE_OPTIONS
-std=c99
-Wno-unused-result
+ -Wno-unused-variable
)
target_compile_options(msg PRIVATE
diff --git a/include/copy.h b/include/copy.h
new file mode 100644
index 0000000..81e543a
--- /dev/null
+++ b/include/copy.h
@@ -0,0 +1,12 @@
+#ifndef __COPY_H
+#define __COPY_H
+
+#include <ftw.h>
+#include <sys/stat.h>
+
+int copy_recursively(const char *fpath,
+ const struct stat *sb,
+ int typeflag,
+ struct FTW *ftwbuf);
+
+#endif
diff --git a/include/engine.h b/include/engine.h
new file mode 100644
index 0000000..a34841a
--- /dev/null
+++ b/include/engine.h
@@ -0,0 +1,6 @@
+#ifndef __ENGINE_H
+#define __ENGINE_H
+
+void ingest(char **buffer);
+
+#endif
diff --git a/include/filehandler.h b/include/filehandler.h
index 8868af7..f1f3342 100644
--- a/include/filehandler.h
+++ b/include/filehandler.h
@@ -3,6 +3,10 @@
#include <stdio.h>
+typedef struct {
+
+} filehandler_t;
+
char *fcontent(FILE *f, unsigned int size);
unsigned int fsize(FILE *f);
diff --git a/include/lexer.h b/include/lexer.h
new file mode 100644
index 0000000..8f7aab1
--- /dev/null
+++ b/include/lexer.h
@@ -0,0 +1,19 @@
+#ifndef __LEXER_H
+#define __LEXER_H
+
+typedef enum { INCLUDE } directive_e;
+
+typedef struct {
+ unsigned int offset;
+ unsigned int length;
+} key_match_t;
+
+typedef struct {
+ directive_e type;
+ void *operands;
+} directive_t;
+
+directive_t *find_directive(char *content, key_match_t *match);
+key_match_t *find_next_key(char *buffer);
+
+#endif
diff --git a/include/template.h b/include/template.h
new file mode 100644
index 0000000..e29e6b5
--- /dev/null
+++ b/include/template.h
@@ -0,0 +1,6 @@
+#ifndef __TEMPLATE_H
+#define __TEMPLATE_H
+
+void template_initialize(char **base_pre, char **base_post);
+
+#endif
diff --git a/src/copy.c b/src/copy.c
new file mode 100644
index 0000000..f63d4f2
--- /dev/null
+++ b/src/copy.c
@@ -0,0 +1,48 @@
+#define _GNU_SOURCE
+
+#include <copy.h>
+#include <fcntl.h>
+#include <filehandler.h>
+#include <ftw.h>
+#include <string.h>
+#include <sys/sendfile.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "../config.h"
+
+int
+copy_recursively(const char *fpath,
+ const struct stat *sb,
+ int typeflag,
+ struct FTW *ftwbuf)
+{
+ (void) sb;
+ (void) ftwbuf;
+
+ const char *path = fpath + strlen(DIRECTORY) + 1;
+ char *output_path = NULL;
+ asprintf(&output_path, "%s/%s", OUTPUT, path);
+
+ if (typeflag == FTW_D) {
+ mkdir(output_path, 0700);
+ return FTW_CONTINUE;
+ }
+
+ if (typeflag != FTW_F)
+ return FTW_CONTINUE;
+
+ FILE *in = fopen(fpath, "r");
+ size_t size = fsize(in);
+ fclose(in);
+
+ int in_fd = open(fpath, O_RDONLY);
+ int out_fd = open(output_path, O_WRONLY | O_CREAT, 0700);
+
+ sendfile(out_fd, in_fd, 0, size);
+
+ close(in_fd);
+ close(out_fd);
+
+ return FTW_CONTINUE;
+}
diff --git a/src/engine.c b/src/engine.c
new file mode 100644
index 0000000..4e4d037
--- /dev/null
+++ b/src/engine.c
@@ -0,0 +1,52 @@
+#define _GNU_SOURCE
+
+#include <engine.h>
+#include <filehandler.h>
+#include <lexer.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../config.h"
+
+void
+ingest(char **buffer)
+{
+ key_match_t *match;
+
+ while (true) {
+ match = find_next_key(*buffer);
+ if (match == NULL)
+ break;
+
+ directive_t *directive = find_directive(*buffer, match);
+ if (directive == NULL)
+ break;
+
+ if (directive->type == INCLUDE) {
+ char *operand = (char *) directive->operands;
+ char *partial_path;
+ asprintf(&partial_path, "%s/%s/%s", DIRECTORY, PARTIALS, operand);
+
+ FILE *f = fopen(partial_path, "r");
+ unsigned int size = fsize(f);
+ char *partial_content = fcontent(f, size);
+
+ char *temp_buffer;
+ asprintf(&temp_buffer, "%s", *buffer);
+
+ free(*buffer);
+ asprintf(buffer,
+ "%.*s%s%s\n",
+ match->offset,
+ temp_buffer,
+ partial_content,
+ temp_buffer + match->offset + match->length);
+
+ free(temp_buffer);
+ }
+
+ free(directive);
+ free(match);
+ }
+}
diff --git a/src/lexer.c b/src/lexer.c
new file mode 100644
index 0000000..34db154
--- /dev/null
+++ b/src/lexer.c
@@ -0,0 +1,81 @@
+#define _GNU_SOURCE
+
+#include <ctype.h>
+#include <lexer.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+key_match_t *
+find_next_key(char *buffer)
+{
+ key_match_t *match = calloc(1, sizeof(key_match_t));
+
+ for (size_t i = 0; i < strlen(buffer) - 1; i++) {
+ if (buffer[i] == '{' && buffer[i + 1] == '{')
+ match->offset = i;
+
+ if (i == strlen(buffer) - 1) {
+ free(match);
+ return NULL;
+ }
+ }
+
+ char *subbuffer = buffer + match->offset;
+ for (size_t i = 0; i < strlen(subbuffer) - 1; i++) {
+ if (subbuffer[i] == '}' && subbuffer[i + 1] == '}')
+ match->length = i + 2;
+
+ if (i == strlen(buffer) - 1) {
+ printf("Unterminated Key\n");
+ free(match);
+ return NULL;
+ }
+ }
+
+ return match;
+}
+
+directive_t *
+find_directive(char *content, key_match_t *match)
+{
+ directive_t *directive = (directive_t *) calloc(1, sizeof(directive_t));
+
+ char *buffer = content + match->offset;
+ unsigned int n = 0;
+
+ for (size_t i = 0; i < match->length; i++)
+ switch (buffer[i]) {
+ case '{':
+ case ' ':
+ case '\t':
+ case '\n':
+ n++;
+ break;
+
+ default:
+ goto found_start;
+ }
+
+ return NULL;
+
+found_start:
+ if (strncmp(buffer + n, "include", strlen("include")) == 0) {
+ directive->type = INCLUDE;
+
+ char *operand = NULL;
+ for (size_t i = n + strlen("include");
+ i < match->length - strlen("include");
+ i++)
+ if (isalnum(buffer[i])) {
+ sscanf(buffer + i, "%ms\"", &operand);
+ operand[strlen(operand) - 1] = '\0';
+ break;
+ }
+
+ asprintf((char **) &directive->operands, "%s", operand);
+ free(operand);
+ }
+
+ return directive;
+}
diff --git a/src/main.c b/src/main.c
index c560fec..b42f5d7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,159 +1,25 @@
#define _GNU_SOURCE
-#include <ctype.h>
-#include <fcntl.h>
+#include <copy.h>
+#include <engine.h>
#include <filehandler.h>
#include <ftw.h>
+#include <lexer.h>
#include <libgen.h>
#include <mkdio.h>
-#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/sendfile.h>
#include <sys/stat.h>
-#include <unistd.h>
+#include <template.h>
#include "../config.h"
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
-
-typedef enum { INCLUDE } directive_e;
-
-typedef struct {
- unsigned int offset;
- unsigned int length;
-} key_match_t;
-
-typedef struct {
- directive_e type;
- void *operands;
-} directive_t;
-
-directive_t *find_directive(char *content, key_match_t *match);
-key_match_t *find_next_key(char *buffer);
void handle_file(const char *path);
-void ingest(char **buffer);
char *base_pre;
char *base_post;
-key_match_t *
-find_next_key(char *buffer)
-{
- key_match_t *match = calloc(1, sizeof(key_match_t));
-
- for (size_t i = 0; i < strlen(buffer) - 1; i++) {
- if (buffer[i] == '{' && buffer[i + 1] == '{')
- match->offset = i;
-
- if (i == strlen(buffer) - 1) {
- free(match);
- return NULL;
- }
- }
-
- char *subbuffer = buffer + match->offset;
- for (size_t i = 0; i < strlen(subbuffer) - 1; i++) {
- if (subbuffer[i] == '}' && subbuffer[i + 1] == '}')
- match->length = i + 2;
-
- if (i == strlen(buffer) - 1) {
- printf("Unterminated Key\n");
- free(match);
- return NULL;
- }
- }
-
- return match;
-}
-
-directive_t *
-find_directive(char *content, key_match_t *match)
-{
- directive_t *directive = (directive_t *) calloc(1, sizeof(directive_t));
-
- char *buffer = content + match->offset;
- unsigned int n = 0;
-
- for (size_t i = 0; i < match->length; i++)
- switch (buffer[i]) {
- case '{':
- case ' ':
- case '\t':
- case '\n':
- n++;
- break;
-
- default:
- goto found_start;
- }
-
- return NULL;
-
-found_start:
- if (strncmp(buffer + n, "include", strlen("include")) == 0) {
- directive->type = INCLUDE;
-
- char *operand = NULL;
- for (size_t i = n + strlen("include");
- i < match->length - strlen("include");
- i++)
- if (isalnum(buffer[i])) {
- sscanf(buffer + i, "%ms\"", &operand);
- operand[strlen(operand) - 1] = '\0';
- break;
- }
-
- asprintf((char **) &directive->operands, "%s", operand);
- free(operand);
- }
-
- return directive;
-}
-
-void
-ingest(char **buffer)
-{
- key_match_t *match;
-
- while (true) {
- match = find_next_key(*buffer);
- if (match == NULL)
- break;
-
- directive_t *directive = find_directive(*buffer, match);
- if (directive == NULL)
- break;
-
- if (directive->type == INCLUDE) {
- char *operand = (char *) directive->operands;
- char *partial_path;
- asprintf(&partial_path, "%s/%s/%s", DIRECTORY, PARTIALS, operand);
-
- FILE *f = fopen(partial_path, "r");
- unsigned int size = fsize(f);
- char *partial_content = fcontent(f, size);
-
- char *temp_buffer;
- asprintf(&temp_buffer, "%s", *buffer);
-
- free(*buffer);
- asprintf(buffer,
- "%.*s%s%s\n",
- match->offset,
- temp_buffer,
- partial_content,
- temp_buffer + match->offset + match->length);
-
- free(temp_buffer);
- }
-
- free(directive);
- free(match);
- }
-}
-
void
handle_file(const char *path)
{
@@ -225,42 +91,6 @@ handle_file(const char *path)
}
int
-copy_recursively(const char *fpath,
- const struct stat *sb,
- int typeflag,
- struct FTW *ftwbuf)
-{
- (void) sb;
- (void) ftwbuf;
-
- const char *path = fpath + strlen(DIRECTORY) + 1;
- char *output_path = NULL;
- asprintf(&output_path, "%s/%s", OUTPUT, path);
-
- if (typeflag == FTW_D) {
- mkdir(output_path, 0700);
- return FTW_CONTINUE;
- }
-
- if (typeflag != FTW_F)
- return FTW_CONTINUE;
-
- FILE *in = fopen(fpath, "r");
- size_t size = fsize(in);
- fclose(in);
-
- int in_fd = open(fpath, O_RDONLY);
- int out_fd = open(output_path, O_WRONLY | O_CREAT, 0700);
-
- sendfile(out_fd, in_fd, 0, size);
-
- close(in_fd);
- close(out_fd);
-
- return FTW_CONTINUE;
-}
-
-int
main(int argc, char **argv)
{
(void) argc;
@@ -272,20 +102,7 @@ main(int argc, char **argv)
return EXIT_FAILURE;
}
- FILE *base = fopen(DIRECTORY "/" BASE_TEMPLATE, "r");
-
- unsigned int size = fsize(base);
- char *contents = fcontent(base, size);
-
- key_match_t *match = find_next_key(contents);
- asprintf(&base_pre, "%.*s", match->offset, contents);
- asprintf(&base_post,
- "%.*s",
- size - match->offset - match->length,
- contents + match->offset + match->length);
-
- free(contents);
- fclose(base);
+ template_initialize(&base_pre, &base_post);
mkdir(OUTPUT, 0700);
nftw(
diff --git a/src/template.c b/src/template.c
new file mode 100644
index 0000000..95a54d9
--- /dev/null
+++ b/src/template.c
@@ -0,0 +1,28 @@
+#define _GNU_SOURCE
+
+#include <filehandler.h>
+#include <lexer.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <template.h>
+
+#include "../config.h"
+
+void
+template_initialize(char **base_pre, char **base_post)
+{
+ FILE *base = fopen(DIRECTORY "/" BASE_TEMPLATE, "r");
+
+ unsigned int size = fsize(base);
+ char *contents = fcontent(base, size);
+
+ key_match_t *match = find_next_key(contents);
+ asprintf(base_pre, "%.*s", match->offset, contents);
+ asprintf(base_post,
+ "%.*s",
+ size - match->offset - match->length,
+ contents + match->offset + match->length);
+
+ free(contents);
+ fclose(base);
+}