diff options
author | Raghuram Subramani <raghus2247@gmail.com> | 2025-08-03 12:24:54 +0530 |
---|---|---|
committer | Raghuram Subramani <raghus2247@gmail.com> | 2025-08-03 12:24:54 +0530 |
commit | 24b9d0e486461a05c15b7ff6a5a2013767e1fc38 (patch) | |
tree | dc228cd088f2f852290ba477d742f361be0e7408 | |
parent | 1a060cc2e39e6ded798a7347a3fc086ba4d73064 (diff) |
engine: split into multiple files
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/engine.c | 299 | ||||
-rw-r--r-- | src/engine/contentfor.c | 54 | ||||
-rw-r--r-- | src/engine/eachdo.c | 138 | ||||
-rw-r--r-- | src/engine/engine.c | 129 | ||||
-rw-r--r-- | src/engine/include.c | 60 |
6 files changed, 385 insertions, 300 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d835e7..9927f6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,10 @@ project(msg C) set(SRC src/config.c src/copy.c - src/engine.c + src/engine/contentfor.c + src/engine/eachdo.c + src/engine/engine.c + src/engine/include.c src/filehandler.c src/lexer.c src/list.c diff --git a/src/engine.c b/src/engine.c deleted file mode 100644 index c9b49f1..0000000 --- a/src/engine.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * msg - * Copyright (C) 2025 Raghuram Subramani <raghus2247@gmail.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "util.h" -#define _GNU_SOURCE - -#include <config.h> -#include <copy.h> -#include <engine.h> -#include <filehandler.h> -#include <lexer.h> -#include <list.h> -#include <msg.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -extern msg_t *msg; - -void -handle_include(char **buffer, key_match_t *match, directive_t *directive) -{ - char *operand = directive->operands; - char *partial_path; - asprintf(&partial_path, "%s/%s/%s", msg->base_directory, PARTIALS, operand); - - FILE *f = fopen(partial_path, "r"); - if (f == NULL) { - printf("Could not open: %s\n", partial_path); - return; - } - free(partial_path); - - unsigned int size = fsize(f); - char *partial_content = fcontent(f, size); - fclose(f); - - char *temp_buffer = strdup(*buffer); - - free(*buffer); - asprintf(buffer, - "%.*s%s%s\n", - match->offset, - temp_buffer, - partial_content, - temp_buffer + match->offset + match->length); - - free(partial_content); - free(temp_buffer); -} - -void -handle_contentfor(char **buffer, - key_match_t *match, - directive_t *directive, - list_t *content_headers) -{ - contentfor_operand_t *operand = directive->operands; - contentfor_operand_t new_operand = { .content = strdup(operand->content), - .key = strdup(operand->key), - .length = operand->length }; - list_add(content_headers, &new_operand); - -#ifdef DEBUG - printf("CONTENTFOR: %s\n", operand->key); - printf("CONTENT: %s\n", operand->content); -#endif - - char *temp_buffer = strdup(*buffer); - - free(*buffer); - asprintf(buffer, - "%.*s%s", - match->offset, - temp_buffer, - temp_buffer + operand->length); - - free(temp_buffer); -} - -void -handle_eachdo(char **buffer, key_match_t *match, directive_t *directive) -{ - eachdo_operands_t *operands = directive->operands; - - engine_t *engine = engine_ingest(&operands->content); - engine_delete(engine); - list_t *directives = lex(operands->content); - -#ifdef DEBUG - printf("KEY: %s\n", operands->key); - printf("CONTENT: %s\n", operands->content); -#endif - - char *path; - - asprintf(&path, "%s/%s", msg->base_directory, trim(operands->key)); - list_t *files = enumfilesindir(path); - free(path); - - if (files == NULL) { - printf("Could not find key %s\n", trim(operands->key)); - free(operands); - return; - } - - list_t *atoms = list_create(sizeof(ptr_wrapper_t)); - size_t length = 1; - - for (size_t i = 0; i < files->size; i++) { - ptr_wrapper_t *file_wrp = list_get(files, i); - asprintf(&path, - "%s/%s/%s", - msg->base_directory, - trim(operands->key), - (char *) file_wrp->ptr); - - int len = strlen(path); - char *comparable = &path[len - strlen("index.html")]; - if (strcmp(comparable, "index.html") == 0) { - free(path); - free(file_wrp->ptr); - continue; - } - - config_t *config = config_fetch_and_parse(path); - - for (size_t i = 0; i < directives->size; i++) { - directive_t *_directive = list_get(directives, i); - switch (_directive->type) { - case _RAW: { - list_wrap_and_add(atoms, strdup(_directive->operands)); - length += strlen(_directive->operands); - break; - } - - case PUT: { - ptr_wrapper_t *key_wrp - = list_find_corresponding_value_from_ptr_wrapper( - config->keys, config->values, trim(_directive->operands)); - - if (key_wrp != NULL) { - list_wrap_and_add(atoms, strdup(key_wrp->ptr)); - length += strlen(key_wrp->ptr); - } - - break; - } - - default: - /* TODO: Handle this */ - break; - } - } - - config_delete(config); - free(file_wrp->ptr); - } - - list_delete(files); - - char *content = calloc(length, sizeof(char)); - - for (size_t i = 0; i < atoms->size; i++) { - ptr_wrapper_t *wrapper = list_get(atoms, i); - strcat(content, (char *) wrapper->ptr); - free(wrapper->ptr); - } - - char *temp_buffer = strdup(*buffer); - - free(*buffer); - asprintf(buffer, - "%.*s%s%s\n", - match->offset, - temp_buffer, - content, - temp_buffer + operands->length); - - for (size_t i = 0; i < directives->size; i++) { - directive_t *_directive = list_get(directives, i); - free(_directive->operands); - } - list_delete(directives); - list_delete(atoms); - free(content); - free(temp_buffer); -} - -engine_t * -engine_ingest(char **buffer) -{ - engine_t *engine = malloc(sizeof(engine_t)); - engine->config = NULL; - - char *p = strstr(*buffer, "---"); - if (p != NULL) { - char *config; - asprintf(&config, "%.*s\n", (int) (p - *buffer), *buffer); - engine->config = config_parse(config); - free(config); - - char *tempbuffer = strdup(p); - - free(*buffer); - asprintf(buffer, "%s", tempbuffer + strlen("---")); - - free(tempbuffer); - } - - key_match_t *match; - engine->content_headers = list_create(sizeof(contentfor_operand_t)); - if (engine->content_headers == NULL) { - printf("Could not create content_headers\n"); - return NULL; - } - - size_t skip = 0; - while (true) { - match = find_next_key(*buffer, skip); - if (match == NULL) - break; - -#ifdef DEBUG - printf("Match: %.*s LENGTH(%d) OFFSET(%d)\n", - match->length, - *buffer + match->offset, - match->length, - match->offset); -#endif - - directive_t *directive = find_directive(*buffer, match); - if (directive == NULL) { - printf( - "Unknown directive: %.*s\n", match->length, *buffer + match->offset); - - break; - } - - switch (directive->type) { - case INCLUDE: - handle_include(buffer, match, directive); - break; - case CONTENTFOR: - handle_contentfor(buffer, match, directive, engine->content_headers); - break; - case EACHDO: - handle_eachdo(buffer, match, directive); - break; - - case PUTPAGE: - /* TODO: handle */ - case PUT: - case ENDEACHDO: - case BODY: - case CONTENT: - case ENDCONTENT: - case _RAW: - skip++; - break; - } - - directive_delete(directive); - free(match); - } - - return engine; -} - -void -engine_delete(engine_t *engine) -{ - if (engine->config != NULL) - config_delete(engine->config); - - for (size_t i = 0; i < engine->content_headers->size; i++) { - contentfor_operand_t *operand = list_get(engine->content_headers, i); - free(operand->content); - free(operand->key); - } - list_delete(engine->content_headers); - free(engine); -} diff --git a/src/engine/contentfor.c b/src/engine/contentfor.c new file mode 100644 index 0000000..a30c3c8 --- /dev/null +++ b/src/engine/contentfor.c @@ -0,0 +1,54 @@ +/* + * msg + * Copyright (C) 2025 Raghuram Subramani <raghus2247@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#define _GNU_SOURCE + +#include <engine.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void +handle_contentfor(char **buffer, + key_match_t *match, + directive_t *directive, + list_t *content_headers) +{ + contentfor_operand_t *operand = directive->operands; + contentfor_operand_t new_operand = { .content = strdup(operand->content), + .key = strdup(operand->key), + .length = operand->length }; + list_add(content_headers, &new_operand); + +#ifdef DEBUG + printf("CONTENTFOR: %s\n", operand->key); + printf("CONTENT: %s\n", operand->content); +#endif + + char *temp_buffer = strdup(*buffer); + + free(*buffer); + asprintf(buffer, + "%.*s%s", + match->offset, + temp_buffer, + temp_buffer + operand->length); + + free(temp_buffer); +} diff --git a/src/engine/eachdo.c b/src/engine/eachdo.c new file mode 100644 index 0000000..564e567 --- /dev/null +++ b/src/engine/eachdo.c @@ -0,0 +1,138 @@ +/* + * msg + * Copyright (C) 2025 Raghuram Subramani <raghus2247@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#define _GNU_SOURCE + +#include <engine.h> +#include <filehandler.h> +#include <msg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <util.h> + +extern msg_t *msg; + +void +handle_eachdo(char **buffer, key_match_t *match, directive_t *directive) +{ + eachdo_operands_t *operands = directive->operands; + + engine_t *engine = engine_ingest(&operands->content); + engine_delete(engine); + list_t *directives = lex(operands->content); + +#ifdef DEBUG + printf("KEY: %s\n", operands->key); + printf("CONTENT: %s\n", operands->content); +#endif + + char *path; + + asprintf(&path, "%s/%s", msg->base_directory, trim(operands->key)); + list_t *files = enumfilesindir(path); + free(path); + + if (files == NULL) { + printf("Could not find key %s\n", trim(operands->key)); + free(operands); + return; + } + + list_t *atoms = list_create(sizeof(ptr_wrapper_t)); + size_t length = 1; + + for (size_t i = 0; i < files->size; i++) { + ptr_wrapper_t *file_wrp = list_get(files, i); + asprintf(&path, + "%s/%s/%s", + msg->base_directory, + trim(operands->key), + (char *) file_wrp->ptr); + + int len = strlen(path); + char *comparable = &path[len - strlen("index.html")]; + if (strcmp(comparable, "index.html") == 0) { + free(path); + free(file_wrp->ptr); + continue; + } + + config_t *config = config_fetch_and_parse(path); + + for (size_t i = 0; i < directives->size; i++) { + directive_t *_directive = list_get(directives, i); + switch (_directive->type) { + case _RAW: { + list_wrap_and_add(atoms, strdup(_directive->operands)); + length += strlen(_directive->operands); + break; + } + + case PUT: { + ptr_wrapper_t *key_wrp + = list_find_corresponding_value_from_ptr_wrapper( + config->keys, config->values, trim(_directive->operands)); + + if (key_wrp != NULL) { + list_wrap_and_add(atoms, strdup(key_wrp->ptr)); + length += strlen(key_wrp->ptr); + } + + break; + } + + default: + /* TODO: Handle this */ + break; + } + } + + config_delete(config); + free(file_wrp->ptr); + } + + list_delete(files); + + char *content = calloc(length, sizeof(char)); + + for (size_t i = 0; i < atoms->size; i++) { + ptr_wrapper_t *wrapper = list_get(atoms, i); + strcat(content, (char *) wrapper->ptr); + free(wrapper->ptr); + } + + char *temp_buffer = strdup(*buffer); + + free(*buffer); + asprintf(buffer, + "%.*s%s%s\n", + match->offset, + temp_buffer, + content, + temp_buffer + operands->length); + + for (size_t i = 0; i < directives->size; i++) { + directive_t *_directive = list_get(directives, i); + free(_directive->operands); + } + list_delete(directives); + list_delete(atoms); + free(content); + free(temp_buffer); +} diff --git a/src/engine/engine.c b/src/engine/engine.c new file mode 100644 index 0000000..b1dccf4 --- /dev/null +++ b/src/engine/engine.c @@ -0,0 +1,129 @@ +/* + * msg + * Copyright (C) 2025 Raghuram Subramani <raghus2247@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#define _GNU_SOURCE + +#include <config.h> +#include <copy.h> +#include <engine.h> +#include <filehandler.h> +#include <lexer.h> +#include <list.h> +#include <msg.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <util.h> + +extern msg_t *msg; + +engine_t * +engine_ingest(char **buffer) +{ + engine_t *engine = malloc(sizeof(engine_t)); + engine->config = NULL; + + char *p = strstr(*buffer, "---"); + if (p != NULL) { + char *config; + asprintf(&config, "%.*s\n", (int) (p - *buffer), *buffer); + engine->config = config_parse(config); + free(config); + + char *tempbuffer = strdup(p); + + free(*buffer); + asprintf(buffer, "%s", tempbuffer + strlen("---")); + + free(tempbuffer); + } + + key_match_t *match; + engine->content_headers = list_create(sizeof(contentfor_operand_t)); + if (engine->content_headers == NULL) { + printf("Could not create content_headers\n"); + return NULL; + } + + size_t skip = 0; + while (true) { + match = find_next_key(*buffer, skip); + if (match == NULL) + break; + +#ifdef DEBUG + printf("Match: %.*s LENGTH(%d) OFFSET(%d)\n", + match->length, + *buffer + match->offset, + match->length, + match->offset); +#endif + + directive_t *directive = find_directive(*buffer, match); + if (directive == NULL) { + printf( + "Unknown directive: %.*s\n", match->length, *buffer + match->offset); + + break; + } + + switch (directive->type) { + case INCLUDE: + handle_include(buffer, match, directive); + break; + case CONTENTFOR: + handle_contentfor(buffer, match, directive, engine->content_headers); + break; + case EACHDO: + handle_eachdo(buffer, match, directive); + break; + + case PUTPAGE: + /* TODO: handle */ + case PUT: + case ENDEACHDO: + case BODY: + case CONTENT: + case ENDCONTENT: + case _RAW: + skip++; + break; + } + + directive_delete(directive); + free(match); + } + + return engine; +} + +void +engine_delete(engine_t *engine) +{ + if (engine->config != NULL) + config_delete(engine->config); + + for (size_t i = 0; i < engine->content_headers->size; i++) { + contentfor_operand_t *operand = list_get(engine->content_headers, i); + free(operand->content); + free(operand->key); + } + list_delete(engine->content_headers); + free(engine); +} diff --git a/src/engine/include.c b/src/engine/include.c new file mode 100644 index 0000000..30cce88 --- /dev/null +++ b/src/engine/include.c @@ -0,0 +1,60 @@ +/* + * msg + * Copyright (C) 2025 Raghuram Subramani <raghus2247@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#define _GNU_SOURCE + +#include <engine.h> +#include <filehandler.h> +#include <msg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +extern msg_t *msg; + +void +handle_include(char **buffer, key_match_t *match, directive_t *directive) +{ + char *operand = directive->operands; + char *partial_path; + asprintf(&partial_path, "%s/%s/%s", msg->base_directory, PARTIALS, operand); + + FILE *f = fopen(partial_path, "r"); + if (f == NULL) { + printf("Could not open: %s\n", partial_path); + return; + } + free(partial_path); + + unsigned int size = fsize(f); + char *partial_content = fcontent(f, size); + fclose(f); + + char *temp_buffer = strdup(*buffer); + + free(*buffer); + asprintf(buffer, + "%.*s%s%s\n", + match->offset, + temp_buffer, + partial_content, + temp_buffer + match->offset + match->length); + + free(partial_content); + free(temp_buffer); +} |