From 958645768939002b3d8f156f8b84b9ab907eb070 Mon Sep 17 00:00:00 2001 From: german Date: Tue, 16 Dec 2025 13:11:40 +0400 Subject: [PATCH] Beta --- .vscode/settings.json | 4 ++ Makefile | 45 +++++++++++++ README.md | 11 +++ example.c | 85 ++++++++++++++++++++++++ handler.h | 41 ++++++++++++ microconf | Bin 0 -> 16368 bytes microconf.h | 151 ++++++++++++++++++++++++++++++++++++++++++ microconf_test.conf | 25 +++++++ 8 files changed, 362 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 Makefile create mode 100644 README.md create mode 100644 example.c create mode 100644 handler.h create mode 100755 microconf create mode 100644 microconf.h create mode 100644 microconf_test.conf diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f14a6a0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "makefile.configureOnOpen": false, + "C_Cpp.errorSquiggles": "disabled" +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..def6eaa --- /dev/null +++ b/Makefile @@ -0,0 +1,45 @@ +# +# Makefile +# +# Copyright 2025 +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. +# +# + +CC=gcc +OPTIONS=-O2 -Wall -ansi +OUTPUT_NAME=microconf +COPY=cp +INPUT_NAME=example.c +REMOVE=rm +INSTALL_NAME=/usr/local/bin/microconf-example +MODE=chmod +x +RUN_OF=./ + +.PHONY: clear run install uninstall + +$(OUTPUT_NAME): $(INPUT_NAME) + $(CC) $(OPTIONS) $(INPUT_NAME) -o $(OUTPUT_NAME) +clear: + $(REMOVE) -f $(OUTPUT_NAME) +run: + $(MODE) $(OUTPUT_NAME) + $(RUN_OF)$(OUTPUT_NAME) +install: + $(COPY) $(OUTPUT_NAME) $(INSTALL_NAME) +uninstall: + $(REMOVE) $(INSTALL_NAME) diff --git a/README.md b/README.md new file mode 100644 index 0000000..975e031 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Microconf +Парсер формата конфигурации. +## Пример +Для компиляции примера используйте: +```bash +cd ~/microconf +make clear +make +./microconf``` +## Версия + - 1.0 - Бета diff --git a/example.c b/example.c new file mode 100644 index 0000000..133e181 --- /dev/null +++ b/example.c @@ -0,0 +1,85 @@ +/* + * example.c + * + * Copyright 2025 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * + */ + + +#include "microconf.h" + +/* Настройки */ + +#define TEST_FILE "microconf_test.conf" +#define LEN_MAX_VAL 20 +#define LEN_MAX_KEY 10 +#define VALS_COUNT 3 + +/* Массивы */ + +char vals[VALS_COUNT][LEN_MAX_VAL] = {""}; +char keys[VALS_COUNT][LEN_MAX_KEY] = {""}; + +/* Готовый обработчик, требует только имена массивов */ + +#define INPUT_KEYS_NUM keys +#define INPUT_VALS_NUM vals + +#include "handler.h" + +/* + * + * Можно определить свой обработчик, например: + * + * save_data_t my_handler(unsigned long num) { + * save_data_t t; + * t.key = keys[num]; + * t.value = vals[num]; + * return t; + * } + * + */ + +int main(void) { + /* Отрыть файл */ + file_t fp = fopen(TEST_FILE, "r"); + /* Функция: + * int microconf_compile ( + * файловая_структура, + * обработчик_ввода, + * максимальная_длинна_ключа, + * максимальная_длинна_значения, + * максимальное_количество_ключей + * ); + */ + int status = microconf_compile(fp, microconf_std_handler, LEN_MAX_KEY, LEN_MAX_VAL, VALS_COUNT); + /* При ошибке - аварийно завершить */ + if (status == EXIT_FAILURE) return status; + /* Вывести в консоль */ + unsigned char num_read = 0; + while (num_read < 3) { + char* key = keys[num_read]; + char* val = vals[num_read]; + printf("Key=%s Value=%s\n", key, val); + num_read ++; + } + /* Закрытие файла и успешное завершение программы */ + fclose(fp); + return EXIT_SUCCESS; +} diff --git a/handler.h b/handler.h new file mode 100644 index 0000000..6f9600a --- /dev/null +++ b/handler.h @@ -0,0 +1,41 @@ +/* + * handler.h + * + * Copyright 2025 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * + */ + + +#if (!defined(__HANDLERS_H_FILE)) +#define __HANDLERS_H_FILE + +#include "microconf.h" + +#if (!defined(INPUT_KEYS_NUM)) || (!defined(INPUT_VALS_NUM)) +#error Please specify array names +#endif + +save_data_t microconf_std_handler(unsigned long num) { + save_data_t t; + t.key = INPUT_KEYS_NUM[num]; + t.value = INPUT_VALS_NUM[num]; + return t; +} + +#endif \ No newline at end of file diff --git a/microconf b/microconf new file mode 100755 index 0000000000000000000000000000000000000000..5155765820953d72081dcda6a720ccfdd2173eae GIT binary patch literal 16368 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 literal 0 HcmV?d00001 diff --git a/microconf.h b/microconf.h new file mode 100644 index 0000000..a1ca800 --- /dev/null +++ b/microconf.h @@ -0,0 +1,151 @@ +/* + * microconf.h + * + * Copyright 2025 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * + */ + + +#if (!defined(__LIB_MICROCONF_PARSER)) +#define __LIB_MICROCONF_PARSER + +#define bool char +#define true 1 +#define is_space_test(x) (x <= 32 && x >= 0) +#define false 0 +#define ulong unsigned long + +#include +#include + +typedef FILE* file_t; +typedef struct { + char* key; + char* value; +} save_data_t; + +int _microconf_read_file(file_t fp, save_data_t (*input_handler) (ulong), size_t max_len, size_t max_len_val, ulong max_cnt) { + + int c; + bool is_comment = false; + bool is_space = true; + bool read_key = false; + bool read_val = false; + ulong num = 0; + size_t key_addr = 0; + size_t val_addr = 0; + save_data_t sv = {NULL, NULL}; + int old = '\0'; + ulong str_num = 0; + + while ((c = getc(fp)) != EOF) { + /* Разделитель - перенос строки ('\n') */ + if (c == '\n') { + is_comment = false; + is_space = true; + read_key = false; + read_val = false; + key_addr = 0; + val_addr = 0; + str_num ++; + } + /* Считать комментарием все до конца строки */ + if (c == '#') is_comment = true; + /* Если символ не входит в комментарий, то: */ + if (!is_comment) { + /* Пропустить пробелы в начале строки */ + if (is_space && !is_space_test(c)) { + is_space = false; + read_key = true; + if (num == max_cnt) { + puts("\033[1mmicroconf: \033[91mThe memory is full!\033[0m Code: READ_COUNT_ERR"); + return EXIT_FAILURE; + } + sv = input_handler(num); + num ++; + key_addr = 0; + val_addr = 0; + } + } + /* Чтение значения */ + if (read_val) { + if (c == '\n' || c == '#' || c == EOF) { + val_addr --; + sv.value[val_addr] = '\0'; + read_val = false; + } + if (read_val) { + if (sv.value != NULL) { + sv.value[val_addr] = c; + } + val_addr ++; + if (key_addr >= max_len) { + puts("\033[1mmicroconf: \033[91mThe memory is full!\033[0m Code: READ_VAL_ERR"); + return EXIT_FAILURE; + } + } + } + /* Чтение ключа */ + if (read_key) { + if (c == ':' && old == ':') { + key_addr --; + sv.key[key_addr] = '\0'; + read_key = false; + read_val = true; + val_addr = 0; + } + if (read_key) { + if (sv.key != NULL) { + sv.key[key_addr] = c; + } + key_addr ++; + if (key_addr >= max_len) { + puts("\033[1mmicroconf: \033[91mThe memory is full!\033[0m Code: READ_KEY_ERR"); + return EXIT_FAILURE; + } + } + } + /* Проверка синтаксиса файла */ + if ((c == '\n' || c == '#' || c == EOF) && read_key) { + printf("\033[1mmicroconf: \033[91mSyntax error on line %lu\033[0m\n", str_num); + return EXIT_FAILURE; + } + /* Сохраняем старое значение в переменную */ + old = c; + + } + return EXIT_SUCCESS; +} + +int microconf_compile(file_t fp, save_data_t (*input_handler) (ulong), size_t max_len, size_t max_len_val, ulong max_cnt) { + if (fp == NULL) { + puts("\033[1mmicroconf: \033[91mUnable to open file!\033[0m"); + return EXIT_FAILURE; + } + rewind(fp); + return _microconf_read_file(fp, input_handler, max_len, max_len_val, max_cnt); +} + +#undef bool +#undef ulong +#undef true +#undef false +#undef is_space_test + +#endif diff --git a/microconf_test.conf b/microconf_test.conf new file mode 100644 index 0000000..d539a30 --- /dev/null +++ b/microconf_test.conf @@ -0,0 +1,25 @@ +# +# microconf_test.conf +# +# Copyright 2025 +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. +# +# + +key_1::value_1 # Value +key_2::value_2 # Value +key_3::value_3 # Value \ No newline at end of file