From 912bf616b687a2101d67d140644d193bd5024cc1 Mon Sep 17 00:00:00 2001 From: ngn Date: Thu, 22 May 2025 20:12:05 +0300 Subject: [PATCH] update doc server to ctorm 1.8.1 Signed-off-by: ngn --- doc/.clang-format | 2 +- doc/.clang-tidy | 35 ++++++++++++++++++ doc/Dockerfile | 2 +- doc/Makefile | 5 ++- doc/docs/privacy.en.json | 4 --- doc/docs/privacy.tr.json | 4 --- doc/inc/docs.h | 10 +++--- doc/inc/file.h | 10 ++++++ doc/inc/util.h | 16 +++------ doc/{docs => pages}/api.en.json | 0 doc/{docs => pages}/api.en.md | 0 doc/{docs => pages}/api.tr.json | 0 doc/{docs => pages}/api.tr.md | 0 doc/{docs => pages}/license.en.json | 0 doc/{docs => pages}/license.en.md | 0 doc/{docs => pages}/license.tr.json | 0 doc/{docs => pages}/license.tr.md | 0 doc/pages/privacy.en.json | 4 +++ doc/{docs => pages}/privacy.en.md | 0 doc/pages/privacy.tr.json | 4 +++ doc/{docs => pages}/privacy.tr.md | 0 doc/src/config.c | 19 ++++++---- doc/src/docs.c | 25 ++++++------- doc/src/file.c | 56 +++++++++++++++++++++++++++++ doc/src/main.c | 14 +++++--- doc/src/routes/cors.c | 3 +- doc/src/routes/get.c | 23 ++++++------ doc/src/routes/list.c | 13 +++---- doc/src/util.c | 51 -------------------------- 29 files changed, 178 insertions(+), 122 deletions(-) create mode 100644 doc/.clang-tidy delete mode 100644 doc/docs/privacy.en.json delete mode 100644 doc/docs/privacy.tr.json create mode 100644 doc/inc/file.h rename doc/{docs => pages}/api.en.json (100%) rename doc/{docs => pages}/api.en.md (100%) rename doc/{docs => pages}/api.tr.json (100%) rename doc/{docs => pages}/api.tr.md (100%) rename doc/{docs => pages}/license.en.json (100%) rename doc/{docs => pages}/license.en.md (100%) rename doc/{docs => pages}/license.tr.json (100%) rename doc/{docs => pages}/license.tr.md (100%) create mode 100644 doc/pages/privacy.en.json rename doc/{docs => pages}/privacy.en.md (100%) create mode 100644 doc/pages/privacy.tr.json rename doc/{docs => pages}/privacy.tr.md (100%) create mode 100644 doc/src/file.c diff --git a/doc/.clang-format b/doc/.clang-format index 3169c4d..69d3e28 100644 --- a/doc/.clang-format +++ b/doc/.clang-format @@ -81,7 +81,7 @@ BreakBeforeTernaryOperators: true BreakConstructorInitializers: BeforeColon BreakInheritanceList: BeforeColon BreakStringLiterals: true -ColumnLimit: 120 +ColumnLimit: 80 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false ConstructorInitializerIndentWidth: 4 diff --git a/doc/.clang-tidy b/doc/.clang-tidy new file mode 100644 index 0000000..0336cb6 --- /dev/null +++ b/doc/.clang-tidy @@ -0,0 +1,35 @@ +--- +# "gnu-zero-variadic-macro-arguments" ignored because we are using GNU99 +# standart + +# "clang-diagnostic-language-extension-token" is ignored because we need the +# asm() extension token + +# "DeprecatedOrUnsafeBufferHandling" ignored because C11 "_s" functions are not +# secure either +Checks: >- + clang-diagnostic-*, + -clang-diagnostic-gnu-zero-variadic-macro-arguments, + -clang-diagnostic-language-extension-token, + clang-analyzer-*, + -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, + portability-*, + performance-*, +WarningsAsErrors: '*' +HeaderFileExtensions: + - '' + - h + - hh + - hpp + - hxx +ImplementationFileExtensions: + - c + - cc + - cpp + - cxx +HeaderFilterRegex: '.*' +ExcludeHeaderFilterRegex: '' +FormatStyle: file +SystemHeaders: false +... + diff --git a/doc/Dockerfile b/doc/Dockerfile index 4dbbc7a..bdb2bca 100644 --- a/doc/Dockerfile +++ b/doc/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/ngn13/ctorm:1.7 +FROM ghcr.io/ngn13/ctorm:1.8.1 WORKDIR /doc diff --git a/doc/Makefile b/doc/Makefile index ff6bf94..3b2620a 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -26,10 +26,13 @@ $(DISTDIR)/%.o: src/%.c format: clang-format -i -style=file $(CSRCS) $(HSRCS) +lint: + clang-tidy --warnings-as-errors --config= $(CSRCS) $(HSRCS) + clean: rm -rf $(DISTDIR) run: ./doc.elf -.PHONY: format clean run +.PHONY: format lint clean run diff --git a/doc/docs/privacy.en.json b/doc/docs/privacy.en.json deleted file mode 100644 index a5f9282..0000000 --- a/doc/docs/privacy.en.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "privacy", - "desc": "Learn how I respect your privacy" -} diff --git a/doc/docs/privacy.tr.json b/doc/docs/privacy.tr.json deleted file mode 100644 index 5d9fb17..0000000 --- a/doc/docs/privacy.tr.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "gizlilik", - "desc": "Gizliliğinize nasıl önem verdiğimi öğrenin" -} diff --git a/doc/inc/docs.h b/doc/inc/docs.h index 659fa14..86ef12f 100644 --- a/doc/inc/docs.h +++ b/doc/inc/docs.h @@ -3,13 +3,13 @@ #include #include -#include "util.h" +#include "file.h" typedef struct { - DIR *dir; - util_file_t *file; - char name[NAME_MAX + 1]; - char *lang; + DIR *dir; + file_t *file; + char name[NAME_MAX + 1]; + char *lang; } docs_t; bool docs_init(docs_t *docs, char *dir); diff --git a/doc/inc/file.h b/doc/inc/file.h new file mode 100644 index 0000000..1699a33 --- /dev/null +++ b/doc/inc/file.h @@ -0,0 +1,10 @@ +#pragma once +#include + +typedef struct { + char *content; + int64_t size; +} file_t; + +file_t *file_load(int dirfd, char *path); +void file_free(file_t *file); diff --git a/doc/inc/util.h b/doc/inc/util.h index 01ef265..66ddad3 100644 --- a/doc/inc/util.h +++ b/doc/inc/util.h @@ -4,16 +4,8 @@ #include #include -typedef struct { - char *content; - uint64_t size; -} util_file_t; - -#define util_toupper(str) \ - for (char *c = str; *c != 0; c++) \ +#define util_toupper(str) \ + for (char *c = str; *c != 0; c++) \ *c = toupper(*c) -uint64_t util_endswith(char *str, char *suf); -void util_send(ctorm_res_t *res, uint16_t code, cJSON *json); -util_file_t *util_file_load(int dirfd, char *path); -void util_file_free(util_file_t *file); -bool util_parse_doc_name(char *name, char **lang, const char *ext); +uint64_t util_endswith(char *str, char *suf); +void util_send(ctorm_res_t *res, uint16_t code, cJSON *json); diff --git a/doc/docs/api.en.json b/doc/pages/api.en.json similarity index 100% rename from doc/docs/api.en.json rename to doc/pages/api.en.json diff --git a/doc/docs/api.en.md b/doc/pages/api.en.md similarity index 100% rename from doc/docs/api.en.md rename to doc/pages/api.en.md diff --git a/doc/docs/api.tr.json b/doc/pages/api.tr.json similarity index 100% rename from doc/docs/api.tr.json rename to doc/pages/api.tr.json diff --git a/doc/docs/api.tr.md b/doc/pages/api.tr.md similarity index 100% rename from doc/docs/api.tr.md rename to doc/pages/api.tr.md diff --git a/doc/docs/license.en.json b/doc/pages/license.en.json similarity index 100% rename from doc/docs/license.en.json rename to doc/pages/license.en.json diff --git a/doc/docs/license.en.md b/doc/pages/license.en.md similarity index 100% rename from doc/docs/license.en.md rename to doc/pages/license.en.md diff --git a/doc/docs/license.tr.json b/doc/pages/license.tr.json similarity index 100% rename from doc/docs/license.tr.json rename to doc/pages/license.tr.json diff --git a/doc/docs/license.tr.md b/doc/pages/license.tr.md similarity index 100% rename from doc/docs/license.tr.md rename to doc/pages/license.tr.md diff --git a/doc/pages/privacy.en.json b/doc/pages/privacy.en.json new file mode 100644 index 0000000..7ad990f --- /dev/null +++ b/doc/pages/privacy.en.json @@ -0,0 +1,4 @@ +{ + "title": "privacy", + "desc": "Privacy policy" +} diff --git a/doc/docs/privacy.en.md b/doc/pages/privacy.en.md similarity index 100% rename from doc/docs/privacy.en.md rename to doc/pages/privacy.en.md diff --git a/doc/pages/privacy.tr.json b/doc/pages/privacy.tr.json new file mode 100644 index 0000000..7555615 --- /dev/null +++ b/doc/pages/privacy.tr.json @@ -0,0 +1,4 @@ +{ + "title": "gizlilik", + "desc": "Gizlilik ilkesi" +} diff --git a/doc/docs/privacy.tr.md b/doc/pages/privacy.tr.md similarity index 100% rename from doc/docs/privacy.tr.md rename to doc/pages/privacy.tr.md diff --git a/doc/src/config.c b/doc/src/config.c index ed7e271..4cdb797 100644 --- a/doc/src/config.c +++ b/doc/src/config.c @@ -11,22 +11,25 @@ option_t options[] = { // name value requied - {"host", "0.0.0.0:7003", true }, // host the server should listen on - {"docs_dir", "./docs", true }, // documentation directory - {"", NULL, false}, + {"host", "0.0.0.0:7003", true }, // host the server should listen on + {"dir", "./pages", true }, // documentation pages directory + {"", NULL, false}, }; bool config_load(config_t *conf) { - bzero(conf, sizeof(*conf)); + memset(conf, 0, sizeof(*conf)); char name_env[OPT_NAME_MAX + 10], name_copy[OPT_NAME_MAX], *value = NULL; conf->options = options; - for (option_t *opt = conf->options; opt->value != NULL; opt++, conf->count++) { - strcpy(name_copy, opt->name); + for (option_t *opt = conf->options; opt->value != NULL; + opt++, conf->count++) { + // convert option name to environment variable name + strncpy(name_copy, opt->name, OPT_NAME_MAX); util_toupper(name_copy); snprintf(name_env, sizeof(name_env), "WEBSITE_%s", name_copy); + // attempt to load the value from the environment if ((value = getenv(name_env)) != NULL) opt->value = value; @@ -36,7 +39,9 @@ bool config_load(config_t *conf) { if (!opt->required || NULL != opt->value) continue; - ctorm_fail("please specify a value for the required config option: %s (%s)", opt->name, name_env); + ctorm_fail("please specify a value for the required config option: %s (%s)", + opt->name, + name_env); errno = EFAULT; return false; } diff --git a/doc/src/docs.c b/doc/src/docs.c index 01802b6..5e068f5 100644 --- a/doc/src/docs.c +++ b/doc/src/docs.c @@ -1,6 +1,6 @@ #include + #include -#include #include #include @@ -9,7 +9,7 @@ #define DOCS_LANG_CODE_LEN 2 -bool __docs_parse_name(docs_t *docs, char *ext) { +bool _docs_parse_name(docs_t *docs, char *ext) { // check the extension uint64_t ext_pos = util_endswith(docs->name, ext); @@ -22,7 +22,8 @@ bool __docs_parse_name(docs_t *docs, char *ext) { // example.en\0json\0 // | // `--- find this - for (docs->lang = docs->name; *docs->lang != 0 && *docs->lang != '.'; docs->lang++) + for (docs->lang = docs->name; *docs->lang != 0 && *docs->lang != '.'; + docs->lang++) continue; if (*docs->lang != '.') @@ -39,11 +40,11 @@ bool __docs_parse_name(docs_t *docs, char *ext) { return strlen(docs->lang) == DOCS_LANG_CODE_LEN && *docs->name != 0; } -void __docs_clean(docs_t *docs) { +void _docs_clean(docs_t *docs) { if (NULL == docs->file) return; - util_file_free(docs->file); + file_free(docs->file); docs->file = NULL; } @@ -53,7 +54,7 @@ bool docs_init(docs_t *docs, char *dir) { return false; } - bzero(docs, sizeof(*docs)); + memset(docs, 0, sizeof(*docs)); return NULL != (docs->dir = opendir(dir)); } @@ -64,15 +65,15 @@ char *docs_next(docs_t *docs, char *name, bool content) { } struct dirent *ent = NULL; - __docs_clean(docs); + _docs_clean(docs); while (NULL != (ent = readdir(docs->dir))) { if (*ent->d_name == '.') continue; - strcpy(docs->name, ent->d_name); + strncpy(docs->name, ent->d_name, NAME_MAX); - if (!__docs_parse_name(docs, content ? ".md" : ".json")) + if (!_docs_parse_name(docs, content ? ".md" : ".json")) continue; if (NULL == name || strncmp(docs->name, name, NAME_MAX) == 0) @@ -84,7 +85,7 @@ char *docs_next(docs_t *docs, char *name, bool content) { return NULL; } - if (NULL == (docs->file = util_file_load(dirfd(docs->dir), ent->d_name))) + if (NULL == (docs->file = file_load(dirfd(docs->dir), ent->d_name))) return NULL; return docs->file->content; @@ -99,8 +100,8 @@ void docs_free(docs_t *docs) { if (NULL == docs) return; - __docs_clean(docs); + _docs_clean(docs); closedir(docs->dir); - bzero(docs, sizeof(*docs)); + memset(docs, 0, sizeof(*docs)); } diff --git a/doc/src/file.c b/doc/src/file.c new file mode 100644 index 0000000..2a3ca7a --- /dev/null +++ b/doc/src/file.c @@ -0,0 +1,56 @@ +#include + +#include +#include + +#include +#include +#include + +#include "file.h" + +file_t *file_load(int dirfd, char *path) { + if (NULL == path) { + errno = EINVAL; + return NULL; + } + + file_t *file = NULL; + int fd = -1; + + // open the taarget file + if ((fd = openat(dirfd, path, O_RDONLY)) < 0) + goto end; // errno set by open + + // allocate a new file structure + if (NULL == (file = calloc(1, sizeof(file_t)))) + goto end; // errno set by malloc + + // calculate the file size + if ((file->size = lseek(fd, 0, SEEK_END)) < 0) + goto end; + + // memory map the file + if (NULL == + (file->content = mmap(0, file->size, PROT_READ, MAP_PRIVATE, fd, 0))) + goto end; // errno set by mmap + +end: + if (fd != -1) + close(fd); + + if (NULL != file && NULL == file->content) { + free(file); + return NULL; + } + + return file; +} + +void file_free(file_t *file) { + if (NULL == file) + return; + + munmap(file->content, file->size); + free(file); +} diff --git a/doc/src/main.c b/doc/src/main.c index 2a3e897..ada2b51 100644 --- a/doc/src/main.c +++ b/doc/src/main.c @@ -1,3 +1,4 @@ +#include #include #include @@ -19,25 +20,28 @@ int main() { return EXIT_FAILURE; } + // initialize the app config ctorm_config_new(&app_config); app_config.disable_logging = true; - app = ctorm_app_new(&app_config); + + // create a new app + app = ctorm_app_new(&app_config); // middlewares - MIDDLEWARE_ALL(app, "/*", route_cors); - MIDDLEWARE_ALL(app, "/*/*", route_cors); + ALL(app, "/*", route_cors); + ALL(app, "/*/*", route_cors); // routes GET(app, "/list", route_list); GET(app, "/get/:name", route_get); - ctorm_app_all(app, route_notfound); + ctorm_app_default(app, route_notfound); ctorm_app_local(app, "config", &conf); ctorm_info("starting the web server on %s", host); if (!ctorm_app_run(app, host)) - ctorm_fail("failed to start the app: %s", ctorm_geterror()); + ctorm_fail("failed to start the app: %s", ctorm_error()); ctorm_app_free(app); return EXIT_SUCCESS; diff --git a/doc/src/routes/cors.c b/doc/src/routes/cors.c index fb6c715..1108a0a 100644 --- a/doc/src/routes/cors.c +++ b/doc/src/routes/cors.c @@ -3,7 +3,8 @@ void route_cors(ctorm_req_t *req, ctorm_res_t *res) { RES_SET("Access-Control-Allow-Origin", "*"); RES_SET("Access-Control-Allow-Headers", - "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, " + "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, " + "Authorization, accept, origin, Cache-Control, " "X-Requested-With"); RES_SET("Access-Control-Allow-Methods", "PUT, DELETE, GET"); } diff --git a/doc/src/routes/get.c b/doc/src/routes/get.c index cec28cf..d402321 100644 --- a/doc/src/routes/get.c +++ b/doc/src/routes/get.c @@ -1,31 +1,30 @@ -#include -#include #include +#include #include -#include -#include +#include #include #include "routes.h" #include "config.h" +#include "util.h" #include "docs.h" void route_get(ctorm_req_t *req, ctorm_res_t *res) { - config_t *conf = REQ_LOCAL("config"); - char *doc_name = REQ_PARAM("name"); - char *docs_dir = config_get(conf, "docs_dir"), *doc_data = NULL; + config_t *conf = REQ_LOCAL("config"); + char *name = REQ_PARAM("name"); + char *dir = config_get(conf, "dir"), *doc_data = NULL; cJSON *json = NULL, *doc_json = NULL; docs_t docs; - if (NULL == doc_name) { + if (NULL == name) { ctorm_fail("documentation name not specified (how did that even happend)"); util_send(res, 500, NULL); goto end; } - if (!docs_init(&docs, docs_dir)) { - ctorm_fail("docs_init failed: %s", ctorm_geterror()); + if (!docs_init(&docs, dir)) { + ctorm_fail("docs_init failed: %s", ctorm_error()); util_send(res, 500, NULL); goto end; } @@ -36,7 +35,7 @@ void route_get(ctorm_req_t *req, ctorm_res_t *res) { goto end; } - while (NULL != (doc_data = docs_next(&docs, doc_name, false))) { + while (NULL != (doc_data = docs_next(&docs, name, false))) { if (NULL == (doc_json = cJSON_Parse(doc_data))) { ctorm_fail("failed to parse JSON: %s (%s)", docs.name, docs.lang); continue; @@ -53,7 +52,7 @@ void route_get(ctorm_req_t *req, ctorm_res_t *res) { docs_reset(&docs); - while (NULL != (doc_data = docs_next(&docs, doc_name, true))) { + while (NULL != (doc_data = docs_next(&docs, name, true))) { if (NULL == (doc_json = cJSON_GetObjectItem(json, docs.lang))) continue; diff --git a/doc/src/routes/list.c b/doc/src/routes/list.c index 7b04b37..59a607c 100644 --- a/doc/src/routes/list.c +++ b/doc/src/routes/list.c @@ -3,21 +3,21 @@ #include #include -#include #include #include "routes.h" #include "config.h" +#include "util.h" #include "docs.h" void route_list(ctorm_req_t *req, ctorm_res_t *res) { - config_t *conf = REQ_LOCAL("config"); - char *docs_dir = config_get(conf, "docs_dir"), *doc_data = NULL; + config_t *conf = REQ_LOCAL("config"); + char *dir = config_get(conf, "dir"), *doc_data = NULL; cJSON *array = NULL, *json = NULL, *doc_json = NULL; docs_t docs; - if (!docs_init(&docs, docs_dir)) { - ctorm_fail("docs_init failed: %s", ctorm_geterror()); + if (!docs_init(&docs, dir)) { + ctorm_fail("docs_init failed: %s", ctorm_error()); util_send(res, 500, NULL); goto end; } @@ -31,7 +31,8 @@ void route_list(ctorm_req_t *req, ctorm_res_t *res) { while (NULL != (doc_data = docs_next(&docs, NULL, false))) { if (NULL == (array = cJSON_GetObjectItem(json, docs.lang)) && NULL == (array = cJSON_AddArrayToObject(json, docs.lang))) { - ctorm_fail("failed to create an array object for the language %s", docs.lang); + ctorm_fail( + "failed to create an array object for the language %s", docs.lang); continue; } diff --git a/doc/src/util.c b/doc/src/util.c index 528e5bb..e879206 100644 --- a/doc/src/util.c +++ b/doc/src/util.c @@ -1,17 +1,8 @@ #include #include -#include -#include - #include -#include -#include #include -#include - -#include -#include #include #include "util.h" @@ -57,45 +48,3 @@ void util_send(ctorm_res_t *res, uint16_t code, cJSON *json) { RES_JSON(json); } - -util_file_t *util_file_load(int dirfd, char *path) { - if (NULL == path) { - errno = EINVAL; - return NULL; - } - - util_file_t *file = NULL; - struct stat buf; - int fd = -1; - - if (NULL == (file = malloc(sizeof(util_file_t)))) - goto end; // errno set by malloc - - if ((fd = openat(dirfd, path, O_RDONLY)) < 0) - goto end; // errno set by open - - if (fstat(fd, &buf) < 0) - goto end; // errno set by fstat - - if (NULL == (file->content = mmap(0, (file->size = buf.st_size), PROT_READ, MAP_PRIVATE, fd, 0))) - goto end; // errno set by mmap - -end: - if (fd != -1) - close(fd); - - if (NULL == file->content) { - free(file); - return NULL; - } - - return file; -} - -void util_file_free(util_file_t *file) { - if (NULL == file) - return; - - munmap(file->content, file->size); - free(file); -}