diff options
author | Raghuram Subramani <raghus2247@gmail.com> | 2025-06-19 11:53:16 +0530 |
---|---|---|
committer | Raghuram Subramani <raghus2247@gmail.com> | 2025-06-19 11:53:16 +0530 |
commit | 7698d438f594665661edf90964f92591b7a29556 (patch) | |
tree | 7c92c3ff429c15a1b97ec13c125f1f32e8613f76 | |
parent | bfdbb1e1316225f5bff0309a1b9008dcff567cf5 (diff) |
(misc): modularize program
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | include/copy.h | 12 | ||||
-rw-r--r-- | include/engine.h | 6 | ||||
-rw-r--r-- | include/filehandler.h | 4 | ||||
-rw-r--r-- | include/lexer.h | 19 | ||||
-rw-r--r-- | include/template.h | 6 | ||||
-rw-r--r-- | src/copy.c | 48 | ||||
-rw-r--r-- | src/engine.c | 52 | ||||
-rw-r--r-- | src/lexer.c | 81 | ||||
-rw-r--r-- | src/main.c | 193 | ||||
-rw-r--r-- | src/template.c | 28 |
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; +} @@ -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); +} |