From 056d9b63d8fb04c3141434688537c97f063b5f83 Mon Sep 17 00:00:00 2001 From: ari melody Date: Thu, 11 Jul 2024 17:51:51 +0100 Subject: [PATCH] string replace! --- src/main.c | 85 ++++++++++++++++++++++++++++++++------------ src/parsers/json.c | 18 ++++++++-- src/string.c | 45 +++++++++++++++++++++++ src/string.h | 8 +++++ src/templater/html.c | 1 + src/templater/html.h | 4 +++ test.html | 12 +++++++ 7 files changed, 148 insertions(+), 25 deletions(-) create mode 100644 src/string.c create mode 100644 src/string.h create mode 100644 src/templater/html.c create mode 100644 src/templater/html.h create mode 100644 test.html diff --git a/src/main.c b/src/main.c index 78136b0..45dcd76 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,7 @@ #include #include #include +#include "string.h" #include "parsers/json.h" typedef enum { @@ -18,7 +19,7 @@ MediaType read_media_type(char *name) { } void print_help() { - printf("usage: compile <-t media_type> <-i input_file> [output_file]\n"); + printf("usage: compile <-t media_type> <-j json_file> <-h html_file> [output_file]\n"); printf("valid media types: music, art, blog\n"); printf("if output_file is not specified, the output will be written to stdout.\n"); } @@ -30,7 +31,8 @@ int main(int argc, char **argv) { } MediaType media_type = -1; - FILE *input_file = NULL; + FILE *json_file = NULL; + FILE *html_file = NULL; size_t optind = 0; for (optind = 1; optind < argc && argv[optind][0] == '-'; optind++) { @@ -43,13 +45,24 @@ int main(int argc, char **argv) { exit(EXIT_FAILURE); } break; - case 'i': + case 'j': if (optind++ >= argc) { - fprintf(stderr, "-i was passed, but no file path was given!\n\n"); + fprintf(stderr, "-j was passed, but no file path was given!\n\n"); exit(EXIT_FAILURE); } - input_file = fopen(argv[optind], "r"); - if (input_file == NULL) { + json_file = fopen(argv[optind], "r"); + if (json_file == NULL) { + fprintf(stderr, "failed to open file %s!\n\n", argv[optind]); + exit(EXIT_FAILURE); + } + break; + case 'h': + if (optind++ >= argc) { + fprintf(stderr, "-h was passed, but no file path was given!\n\n"); + exit(EXIT_FAILURE); + } + html_file = fopen(argv[optind], "r"); + if (html_file == NULL) { fprintf(stderr, "failed to open file %s!\n\n", argv[optind]); exit(EXIT_FAILURE); } @@ -65,44 +78,72 @@ int main(int argc, char **argv) { print_help(); exit(EXIT_FAILURE); } - if (input_file == NULL) { - fprintf(stderr, "input file not provided!\n\n"); + if (json_file == NULL) { + fprintf(stderr, "JSON file not provided!\n\n"); + print_help(); + exit(EXIT_FAILURE); + } + if (html_file == NULL) { + fprintf(stderr, "HTML file not provided!\n\n"); print_help(); exit(EXIT_FAILURE); } // get length of file - fseek(input_file, (long)-sizeof(char), SEEK_END); - size_t length = ftell(input_file); - fseek(input_file, 0, SEEK_SET); + fseek(json_file, (long)-sizeof(char), SEEK_END); + size_t json_length = ftell(json_file); + fseek(json_file, 0, SEEK_SET); // read file to buffer - char buf[length + 1]; - fread(buf, 1, length, input_file); - buf[length] = '\0'; + char json_buf[json_length + 1]; + fread(json_buf, 1, json_length, json_file); + json_buf[json_length] = '\0'; // parse the file size_t offset = 0; - JsonObject *json = json_parse(buf, &offset); + JsonObject *json = json_parse(json_buf, &offset); if (json == NULL) { fprintf(stderr, "failed to parse input file!\n"); exit(EXIT_FAILURE); } - printf("title: %s\n", (char*)((JsonObject*)json_get(json, "title"))->value); - printf("type: %s\n", (char*)((JsonObject*)json_get(json, "type"))->value); - printf("year: %.0f\n", *(float*)((JsonObject*)json_get(json, "year"))->value); - printf("artwork: %s\n", (char*)((JsonObject*)json_get(json, "artwork"))->value); - printf("buylink: %s\n", (char*)((JsonObject*)json_get(json, "buylink"))->value); + char *title = (char*)((JsonObject*)json_get(json, "title"))->value; + char *type = (char*)((JsonObject*)json_get(json, "type"))->value; + float year = *(float*)((JsonObject*)json_get(json, "year"))->value; + char *artwork = (char*)((JsonObject*)json_get(json, "artwork"))->value; + char *buylink = (char*)((JsonObject*)json_get(json, "buylink"))->value; + printf("title: %s\n", title); + printf("type: %s\n", type); + printf("year: %.0f\n", year); + printf("artwork: %s\n", artwork); + printf("buylink: %s\n", buylink); JsonObject *links = (JsonObject*)json_get(json, "links"); for (size_t i = 0; i < links->length; i++) { char path[256]; sprintf(path, "links.%zu.title", i); - printf("%s: %s\n", path, (char*)((JsonObject*)json_get(json, path))->value); + char *title = (char*)((JsonObject*)json_get(json, path))->value; sprintf(path, "links.%zu.url", i); - printf("%s: %s\n", path, (char*)((JsonObject*)json_get(json, path))->value); + char *url = (char*)((JsonObject*)json_get(json, path))->value; + printf("links.%zu.title: %s\n", i, title); + printf("links.%zu.url: %s\n", i, url); } + // get length of file + fseek(html_file, (long)-sizeof(char), SEEK_END); + size_t html_length = ftell(html_file); + fseek(html_file, 0, SEEK_SET); + + // read file to buffer + char html_buf[html_length + 1]; + fread(html_buf, 1, html_length, html_file); + html_buf[html_length] = '\0'; + + char *html_out = strrep(html_buf, "{title}", title); + + printf("%s\n", html_out); + + json_free(json); + return 0; } diff --git a/src/parsers/json.c b/src/parsers/json.c index ded164e..2c10b83 100644 --- a/src/parsers/json.c +++ b/src/parsers/json.c @@ -217,6 +217,7 @@ JsonObject *json_parse(char *data, size_t *offset) { if (data[i] != ':') { json_log("error: ':' does not succeed attribute definition", data, i); free(name); + name = NULL; return NULL; } i++; @@ -226,6 +227,7 @@ JsonObject *json_parse(char *data, size_t *offset) { if (value == NULL) { free(name); + name = NULL; return NULL; } @@ -237,7 +239,8 @@ JsonObject *json_parse(char *data, size_t *offset) { obj = malloc(sizeof(JsonObject)); obj->name = name; obj->type = type; - obj->value = value; + if (type != array) + obj->value = value; if (type == array) { obj->children = value; JsonObject *child = obj->children; @@ -344,13 +347,22 @@ void json_free(JsonObject *object) { if (object->children != NULL) { json_free(object->children); + object->children = NULL; } if (object->next != NULL) { json_free(object->next); + object->next = NULL; } - if (object->name != NULL) free(object->name); - if (object->value != NULL) free(object->value); + if (object->name != NULL) { + free(object->name); + object->name = NULL; + } + if (object->value != NULL) { + free(object->value); + object->value = NULL; + } free(object); + object = NULL; } diff --git a/src/string.c b/src/string.c new file mode 100644 index 0000000..c7b29ad --- /dev/null +++ b/src/string.c @@ -0,0 +1,45 @@ +#include "string.h" +#include +#include +#include + +char *strrep(char *src, char *target, char *replace) { + size_t src_len = strlen(src); + size_t target_len = strlen(target); + size_t replace_len = strlen(replace); + size_t count; + size_t start; + char *result; + char *tmp; + char *find; + + find = src; + for (count = 0; (tmp = strstr(find, target)); ++count) { + find = tmp + target_len; + } + + if (count == 0) { + return src; + } + + tmp = result = malloc(sizeof(char) * ( src_len + (replace_len - target_len) + 1 )); + + if (!result) return NULL; + + while (count--) { + // find replacement point + start = strstr(src, target) - src; + // copy pre-target + tmp = strncpy(tmp, src, start) + start; + // printf("PRE-TARGET:\n%s\n\n", result); + // copy replacement + tmp = strcpy(tmp, replace) + replace_len; + // printf("REPLACE:\n%s\n\n", result); + // copy post-replacement + strcpy(tmp, src + start + target_len); + // printf("POST-REPLACE:\n%s\n\n", result); + src += start + target_len; + } + + return result; +} diff --git a/src/string.h b/src/string.h new file mode 100644 index 0000000..ab41500 --- /dev/null +++ b/src/string.h @@ -0,0 +1,8 @@ +#ifndef _def_string_utils +#define _def_string_utils + +#include + +char *strrep(char *src, char *target, char *replace); + +#endif // _def_string_utils diff --git a/src/templater/html.c b/src/templater/html.c new file mode 100644 index 0000000..f2d7f1b --- /dev/null +++ b/src/templater/html.c @@ -0,0 +1 @@ +#include "html.h" diff --git a/src/templater/html.h b/src/templater/html.h new file mode 100644 index 0000000..10a4b90 --- /dev/null +++ b/src/templater/html.h @@ -0,0 +1,4 @@ +#ifndef _def_html_templater +#define _def_html_templater + +#endif // _def_html_templater diff --git a/test.html b/test.html new file mode 100644 index 0000000..3fef118 --- /dev/null +++ b/test.html @@ -0,0 +1,12 @@ + + + + + + {title} + + + +

{title}

+ +